Shared secret for agent enrollment. Generate: openssl rand -hex 32
APP_ENCRYPTION_KEY
—
Yes
AES encryption key for sensitive data at rest
MFA_ENCRYPTION_KEY
—
Yes
Encryption key for MFA secrets
ENROLLMENT_KEY_PEPPER
—
Yes
HMAC pepper for enrollment key hashing
MFA_RECOVERY_CODE_PEPPER
—
Yes
HMAC pepper for recovery code hashing
ENROLLMENT_KEY_DEFAULT_TTL_MINUTES
60
Default enrollment key expiry
ENROLLMENT_KEY_CLEANUP_ENABLED
true
Set to false to disable the daily sweep that purges expired enrollment keys
ENROLLMENT_KEY_PURGE_AFTER_DAYS
7
Grace period (days past expiry) before an expired enrollment key is purged
SESSION_SECRET
—
Yes
Express session signing secret
SESSION_MAX_AGE
86400000
Session max age in ms (24h)
Access-token (15m) and refresh-token (7d) lifetimes are fixed in code
(apps/api/src/services/jwt.ts) — short-lived access tokens backed by
refresh-token rotation — and are intentionally not configurable via
deployment env vars.
Public API URL used for generated agent installers and shareable links. The bundled docker-compose.yml derives this from BREEZE_DOMAIN. If you use a custom compose file, you must set PUBLIC_API_URL in .envand map it into the api service environment: block, or Generate Link / Download Installer will fail with Server URL not configured.
API_URL
—
Legacy fallback for PUBLIC_API_URL, honored only by enrollment, installer, and MCP-invite code paths. Auto-update, dev-push, and a few other routes read PUBLIC_API_URL only — prefer setting PUBLIC_API_URL.
BREEZE_DOMAIN
—
Yes (prod)
Domain for Caddy TLS provisioning
ACME_EMAIL
—
Yes (prod)
Email for Let’s Encrypt certificate notifications
CORS_ALLOWED_ORIGINS
—
Comma-separated allowed CORS origins
IS_HOSTED
—
Yes (prod)
true for hosted SaaS edition, false for self-hosted. Must be set explicitly — the API refuses to boot otherwise. Controls signup gating, billing, and email-verification policy.
TRUST_PROXY_HEADERS
—
Yes (prod)
true when behind a reverse proxy (Caddy, Cloudflare). Must be set explicitly in production.
TRUSTED_PROXY_CIDRS
—
When TRUST_PROXY_HEADERS=true
Comma-separated CIDRs of trusted reverse proxies (e.g., 10.0.0.0/8,172.16.0.0/12). Required when proxy headers are trusted.
IP_ALLOWLIST_ENFORCEMENT_MODE
enforce
Partner dashboard IP allowlist mode. Use off only as a break-glass switch if an allowlist locks everyone out. The allowlist only enforces when a partner has entries configured and proxy trust is working through TRUST_PROXY_HEADERS plus TRUSTED_PROXY_CIDRS.
Public origin for customer-portal links in outbound email (e.g. invoice emails). Falls back to PUBLIC_APP_URL if unset. The portal is served under /portal on the main domain.
PORTAL_BASE_PATH
/portal
Base path the customer portal is served under. Baked into the portal image at build time — changing it requires rebuilding the portal image and keeping the Caddy /portal route in sync.
Comma-separated raw base64 Ed25519 public keys that sign release manifests. Use the published default for official Breeze releases (it is a public key, safe to commit); only change it if you sign your own binaries. The API refuses to start in production without it. BREEZE_RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS is accepted as an alias.
AGENT_AUTO_PROMOTE
true
Controls whether a newly registered/synced agent release immediately becomes the fleet upgrade target. true (default): publishing a release promotes it to the fleet at once. false: new binaries stay downloadable but the fleet only advances when you explicitly promote a version (platform admin + MFA) — see Controlled agent fleet rollout.
See Binary Distribution for details on local vs GitHub mode and S3 offloading.
The Breeze stack includes a coturn TURN server for WebRTC relay. Without TURN, remote desktop connections fail when either peer is behind symmetric NAT or a restrictive firewall.
Variable
Default
Required
Description
TURN_HOST
—
Yes (prod)
Public IP or hostname of the TURN server. Must be reachable by agents and viewers.
Both API and web Sentry integrations are off by default. Leave the DSN variables blank to disable. See Error Tracking & Privacy for what gets collected and how scrubbing works.
Variable
Default
Description
SENTRY_DSN
—
API Sentry DSN. Leave blank to disable server-side error tracking.
SENTRY_ENVIRONMENT
production
Sentry environment tag
SENTRY_RELEASE
—
Sentry release tag (e.g. git SHA)
SENTRY_TRACES_SAMPLE_RATE
0.1
Sentry performance trace sample rate (0.0-1.0)
SENTRY_PROFILES_SAMPLE_RATE
—
API performance-profiling sample rate (0.0-1.0). Leave blank to disable profiling.
PUBLIC_SENTRY_DSN_WEB
—
Web Sentry DSN. Leave blank to disable browser error tracking and on-error session replay. Inlined into the web bundle at build time.
SENTRY_AUTH_TOKEN
—
Sentry auth token used during the web build to upload source maps. If unset, source map upload is skipped and the build still succeeds.
Two rate-limit tiers protect the API. The generic per-user limit covers logged-in dashboard usage; the per-org agent limit caps how much traffic a single tenant’s fleet can generate, even with thousands of agents.
Variable
Default
Description
RATE_LIMIT_WINDOW_MS
60000
Sliding window duration (ms)
RATE_LIMIT_MAX_REQUESTS
100
Max requests per window
AGENT_ORG_RATE_LIMIT_PER_MIN
600
Per-organization sliding-window rate limit on agent-authenticated endpoints. Returns 429 with Retry-After: 60 when exceeded. Sized for ~5 active agents per org; raise for MSPs with very large fleets.
Maximum postgres-js connection pool size. Tune up if you see cascading 504s during heartbeat storms; confirm Postgres max_connections has headroom (default 100 is fine for a single API replica).
Portal state backend: memory or redis (auto redis in production)
PUBLIC_ENABLE_EDR_INTEGRATIONS
false
Surface the EDR UI: the /security/edr fleet page, the device Security-tab EDR panel, and the Security dashboard summary cards. Set true at web image build time to enable.
PUBLIC_ENABLE_NETWORK_DEVICES_IN_LIST
false
Surface network-discovered assets alongside agent endpoints in the Devices list view. Set true at web image build time to enable.
Azure AD app (client) ID for multi-tenant M365 backup. When set with the secret below, enables one-click admin consent flow for connecting Microsoft 365 backups.
C2C_M365_CLIENT_SECRET
—
Azure AD app client secret for multi-tenant M365 backup
These enable partners to connect a Microsoft 365 shared support mailbox so customer email becomes tickets and replies are sent from that mailbox. This is a separate Azure app registration from the Cloud-to-Cloud Backup app above.
Variable
Default
Description
TICKET_MAILBOX_M365_CLIENT_ID
—
Azure AD app (client) ID for the Breeze Ticketing app. When set with the secret, the Microsoft 365 mailbox card appears under Settings → Ticketing → Inbound Email.
TICKET_MAILBOX_M365_CLIENT_SECRET
—
Client secret for the Breeze Ticketing Azure app.
PUBLIC_TICKET_MAILBOX_APP_ID
—
Build-time, browser-exposed app id shown in the Application Access Policy PowerShell snippet on the settings card. Safe to publish – it is the app’s public client id.
Self-hosted only. Point the AI Agent at an Anthropic-compatible /v1/messages backend (vLLM 0.23+, LiteLLM). Must be an http(s) URL. Permitted only when IS_HOSTED is explicitly false (or 0/no/off); refused at boot if IS_HOSTED is true, unset, or invalid.
ANTHROPIC_AUTH_TOKEN
—
Bearer token for the custom backend (use instead of ANTHROPIC_API_KEY when ANTHROPIC_BASE_URL is set).
ANTHROPIC_MODEL
claude-sonnet-4-6
Override the default model id for a raw vLLM backend. Leave unset with a LiteLLM gateway that aliases claude-sonnet-4-6 → your model.
Self-hosted: alternative Anthropic-compatible backends
A self-hosted operator can run the AI Agent against any backend that speaks the
Anthropic /v1/messages dialect — keeping full tool-use and the aiGuardrails
stack — by setting:
Terminal window
IS_HOSTED=false# required — ANTHROPIC_BASE_URL is refused otherwise
ANTHROPIC_BASE_URL=http://localhost:8000# your vLLM / LiteLLM endpoint
ANTHROPIC_AUTH_TOKEN=<backendbearertoken>
# Raw vLLM only — match the served model id (skip with a LiteLLM alias):
ANTHROPIC_MODEL=<served-model-id>
The recommended route is a LiteLLM gateway that aliases claude-sonnet-4-6
to your backend model, so no ANTHROPIC_MODEL override is needed. For an
OpenAI-dialect-only endpoint, use the separate MCP_LLM_* openai-compatible
path instead (chat-only, no tool-use).
ANTHROPIC_BASE_URL is fail-closed: it is honored only when self-host is
affirmatively declared (IS_HOSTED explicitly false/0/no/off). If
IS_HOSTED is true, unset, or set to an unrecognized value, the API refuses
to boot when ANTHROPIC_BASE_URL is present, and the value is also stripped
from the SDK subprocess environment — so a stray or unmapped IS_HOSTED can
never redirect platform AI traffic to a third-party endpoint.
Cost tracking is best-effort. The SDK can’t price a non-Anthropic model id, so
it reports total_cost_usd: 0; Breeze then falls back to token-based pricing,
and an unrecognized model id is priced at conservative Opus-tier
DEFAULT_PRICING ($5/$25 per MTok) — i.e. likely an over-estimate for a
cheap local model, not $0. For accurate accounting, add the served model id to
MODEL_PRICING in aiCostTracker.ts, or use the openai-compatible path’s
MCP_LLM_PRICE_* overrides.
Optional NIST NVD API key. Raises NVD request rate limits so vulnerability feed syncs run faster. Without it, syncs use the slower public rate; the feature works either way.