Docs/Build & operate
Configuration reference

Configuration variables

A complete reference for Probara service, frontend, agent, maintenance, and deployment environment variables, including code defaults and the variables that Docker Compose and Helm actually wire.

How configuration is resolved

Each Go process reads environment variables directly. A code default only applies after the variable reaches the process; Docker Compose and the Helm chart expose smaller, different subsets of the complete runtime surface.

Code default
The value selected by shared/config when the process environment does not contain the variable.
Docker wiring
A variable explicitly listed beneath a service in docker-compose.yml. The root .env file is used for Compose interpolation, but it is not passed wholesale into containers.
Helm wiring
A chart value rendered into a workload environment. The chart has no general extraEnv escape hatch in the current dev state.
Local-process wiring
Defaults exported by scripts/start-local-services.sh before it launches locally built binaries.

Common service variables

Where a table row below says a variable is “not exposed” by a deployment method, it means there is no dedicated Compose declaration or Helm value for it. In Helm, any such variable can still be injected without template changes via extraEnv (all workloads) or <service>.extraEnv — see Helm values. In Compose, add it to the service environment block explicitly.

VariableCode default / validationUsed byDeployment notes
HTTP_PORTRequired integer; no code defaultEvery Go serviceRequired even for scheduler and alerter, whose operational endpoint is normally the metrics listener.
METRICS_PORTRequired integer; no code defaultEvery Go serviceHosts /healthz, /readyz, and /metrics for scheduler, worker, alerter, and the status service.
LOG_LEVELinfoEvery Go serviceCompose and Helm set this explicitly. Use a supported structured logger level such as debug, info, warn, or error.
POSTGRES_URLEmptyAPI, scheduler, worker, alerter, status page, CLIsRequired by API, scheduler, alerter, and status page. Optional for workers; a worker without it cannot run notification or AI-RCA side consumers.
NATS_URLnats://localhost:4222API, scheduler, worker, alerter, status page updatesScheduler and worker require NATS. API and status live-update paths degrade when it is unavailable; alerter can run synchronous dispatch without it.

API authentication, sessions, and audit

VariableCode default / validationDocker / Helm wiring
ADMIN_JWT_SECRETRequired; validation only rejects an empty value. Use at least 32 random characters.Compose ships an insecure hardcoded default and the Helm values ship a placeholder default; override both for production.
ADMIN_ACCESS_TTL_MINUTES15; integerLocal-process script sets it. Compose and Helm rely on the code default.
ADMIN_REFRESH_TTL_DAYS30; integerLocal-process script sets it. Compose and Helm rely on the code default.
ADMIN_COOKIE_SECUREfalse; booleanLocal-process script sets false. Compose and Helm do not expose it; production HTTPS deployments should wire true.
ADMIN_BCRYPT_COST12; integerNot exposed by Compose or Helm. Also used by the admin creation CLI.
AUDIT_RETENTION_DAYS365; nonnegative integer; 0 keeps records foreverCompose and Helm expose the audit-retention setting; the API owns pruning.

The access cookie is HttpOnly and SameSite=Lax. ADMIN_COOKIE_SECURE controls its Secure attribute. Access and refresh TTL values are only parsed as integers; the loader does not reject zero or negative values, so use deliberate positive settings.

Public URLs and private-location authorization

VariableCode default / validationPurpose and caveats
PUBLIC_BASE_URLEmpty; surrounding whitespace and trailing slash removedExternally reachable API origin used in agent installers, push webhooks, and the default OIDC callback. Compose and Helm require it for normal deployment.
PUBLIC_NATS_URLEmptyBroker address embedded in private-location deployment instructions. When deployment information is generated, only tls:// and wss:// URLs are accepted; pre-existing URL credentials are rejected.
NATS_LOCATION_AUTH_ISSUER_SEEDEmptyRequired whenever PUBLIC_NATS_URL is nonempty. It must be a NATS account seed for the API-hosted authorization callout.
WORKER_LOCATION_IDEmpty or UUIDPins a worker to one private location. Empty selects the default platform worker fleet.
LOCATION_CREDENTIALEmptyRequired if and only if WORKER_LOCATION_ID is set. Generated credentials are URL-safe base64 for 32 random bytes.

OIDC single sign-on

VariableDefault / validationDescription
OIDC_ENABLEDfalse; booleanEnables platform-wide OIDC discovery and login.
OIDC_ISSUER_URLRequired when enabledIssuer URL used for OIDC discovery.
OIDC_CLIENT_IDRequired when enabledRegistered OAuth/OIDC client identifier.
OIDC_CLIENT_SECRETRequired when enabledConfidential client secret; store in a secret manager or Kubernetes Secret.
OIDC_REDIRECT_URLDefaults to PUBLIC_BASE_URL + /api/v1/auth/oidc/callbackMust be supplied explicitly if PUBLIC_BASE_URL is empty.
OIDC_SCOPESopenid profile emailWhitespace-separated scopes. Add groups when using OIDC group mappings — many IdPs (Okta among them) only emit the groups claim when the scope is requested.
OIDC_GROUPS_CLAIMgroupsID-token claim read for group→role mappings. The mapping rules themselves live in the database (Settings → OIDC group mappings), not in environment variables.
OIDC_PROVIDER_LABELSSOHuman-readable login-provider label.
OIDC_JIT_PROVISIONtrue; booleanCreates a local user record for a valid first-time OIDC identity.
OIDC_JIT_DEFAULT_ROLEviewer; one of admin, editor, viewerDefault tenant role for JIT users. Ignored whenever any OIDC group mappings exist — mapped roles replace the JIT defaults entirely.
OIDC_JIT_DEFAULT_TENANT_ID00000000-0000-0000-0000-000000000001Tenant receiving JIT users. The loader does not validate UUID syntax; verify it refers to the intended tenant.

Compose includes development-oriented Dex defaults under its optional profile. Helm exposes the platform OIDC settings and stores the client secret separately. In production, register an exact HTTPS callback and choose the least-privileged JIT role.

Encryption-at-rest keys

VariableFormatBehavior
PROBARA_SECRETS_KEYBase64 encoding of exactly 32 bytesVersion 1 key for encrypted channel, monitor, location, and AI credentials.
PROBARA_SECRETS_KEY_V2 … PROBARA_SECRETS_KEY_V100Each is base64 encoding of exactly 32 bytesOptional rotation keys. The highest configured version encrypts new writes; older keys remain available for decryption.
Generate a 32-byte base key
openssl rand -base64 32

API queues, AI fallback, mesh, and artifacts

VariableCode defaultUse / deployment status
ALERT_STREAMALERTSLoaded by the API but not used by a current API runtime path.
ALERT_SUBJECTalertsAPI alert live-update subscriber subject.
ALERT_CONSUMER_NAMEapi-alertsLoaded but not currently used.
CHECK_JOB_STREAMCHECK_JOBSNATS authorization permissions and job topology. Compose and Helm pass the scheduler stream to API.
CHECK_JOB_SUBJECTcheck.jobsOn-demand check publication. Compose and Helm pass the scheduler/worker subject to API; keep all three aligned.
CHECK_RESULT_SUBJECTcheck.resultsPrivate-location result permission and result contract.
AI_RCA_SUBJECTai.rca.jobsAI root-cause job publication; must match worker.
MESH_PROBE_INTERVAL_SECONDS30; positive integerMirrors scheduler cadence so API staleness calculations agree.
MESH_PROBE_TIMEOUT_SECONDS5; positive integerMirrors scheduler probe timeout.
SYNTHETIC_BROWSER_ARTIFACTS_DIROS temporary directory + probara/synthetic-browser-artifactsAPI reads and workers write browser artifacts. Compose shares a volume; Helm currently does not.
Global AI fallback variableDefault / validationNotes
LLM_PROVIDERopenai_compatAccepted runtime providers: openai_compat and openai.
LLM_BASE_URLEmptyBase endpoint for an OpenAI-compatible provider.
LLM_API_KEYEmptyProvider secret.
LLM_MODELEmptyRequired when a base URL is configured.
LLM_JSON_MODEEmptyProduct settings support empty/off, json_object, and json_schema.
LLM_MAX_TOKENS1024; positive integerMaximum response tokens.
LLM_TIMEOUT_SECONDS60; positive integerProvider request timeout.

These LLM values are an optional global fallback. Tenant-specific AI settings stored in PostgreSQL take precedence. Compose and Helm do not currently inject the fallback variables into API or worker pods. The API derives an AIAnalysisEnabled flag from LLM_BASE_URL, but that flag has no present runtime use.

Scheduler and result-ingest variables

VariableCode default / validationCompose / Helm notes
SCHEDULE_INTERVAL_SECONDS2; positive integerCompose and Helm override to 5.
SCHEDULER_BATCH_SIZE500; positive integerNot exposed by Compose or Helm.
CHECK_JOB_STREAMCHECK_JOBSCompose and Helm override to check-jobs.
CHECK_JOB_SUBJECTcheck.jobsCompose and Helm override to check.job.
CHECK_RESULT_STREAMCHECK_RESULTSNot exposed by Compose or Helm.
CHECK_RESULT_SUBJECTcheck.resultsNot exposed by Compose or Helm.
RESULT_INGEST_CONSUMER_NAMEresult-ingestNot exposed by Compose or Helm.
RESULT_INGEST_CONCURRENCY10; positive integerNot exposed by Compose or Helm.
RESULT_INGEST_ENABLEDtrue; booleanNot exposed by Compose or Helm. false means worker results are published but not persisted.
CHECK_JOB_LEGACY_CONSUMERScheck-workers,workerComma-separated old filterless durable consumers deleted at scheduler startup.
RETENTION_CLEANUP_ENABLEDtrue; booleanExposed by Compose and Helm.
RETENTION_CLEANUP_HOUR_UTC2; integer 0–23Exposed by Compose and Helm.
RETENTION_CLEANUP_BATCH_SIZE5000; positive integerExposed by Compose and Helm.
RETENTION_CLEANUP_MAX_ROWS_PER_RUN200000; positive integerExposed by Compose and Helm.
MONITOR_PURGE_ENABLEDtrue; booleanNot exposed by Compose or Helm.
MONITOR_PURGE_INTERVAL_SECONDS30; positive integerNot exposed by Compose or Helm.
MONITOR_PURGE_BATCH_SIZE5000; positive integerNot exposed by Compose or Helm.
MONITOR_PURGE_MAX_ROWS_PER_RUN200000; positive integerNot exposed by Compose or Helm.
MESH_ENABLEDtrue; booleanNot exposed by Compose or Helm.
MESH_PROBE_INTERVAL_SECONDS30; positive integerNot exposed by Compose or Helm.
MESH_PROBE_TIMEOUT_SECONDS5; positive integerNot exposed by Compose or Helm.
MESH_FAILURE_THRESHOLD3; positive integerNot exposed by Compose or Helm.
MESH_SCHEDULE_BATCH_SIZE500; positive integerNot exposed by Compose or Helm.

Worker execution and network-policy variables

VariableCode default / validationNotes
WORKER_CONCURRENCY10; positive integerConcurrent check-job handlers.
NATS_CONSUMER_NAMEcheck-workersCompose and Helm override to worker for the default fleet.
CHECK_JOB_STREAMCHECK_JOBSMust match scheduler.
CHECK_JOB_SUBJECTcheck.jobsMust match scheduler and API.
CHECK_RESULT_STREAMCHECK_RESULTSResult work-queue stream.
CHECK_RESULT_SUBJECTcheck.resultsResult publication subject.
MAX_HTTP_TIMEOUT_SECONDS30; integerLoaded but currently unused outside the configuration object.
MAX_BODY_SIZE_BYTES1048576; positive integerMaximum HTTP response body accepted by the worker.
HTTP_BLOCK_PRIVATE_IPSfalse; booleanWhen enabled, blocks private, loopback, link-local, and reserved destinations across networked check types.
HTTP_ALLOWED_CIDRSEmpty; comma-separated CIDRsNarrow exceptions to the block policy. Any invalid CIDR fails startup.
CHROME_BINAutodetect common Chromium/Chrome namesOverride the browser executable. The worker image sets /usr/bin/chromium-browser.
SIP_LOCALHOST_AS_HOST_GATEWAYfalseTruthy values are 1, true, yes, and on. Compose/local set it for host-gateway development.

Worker AI and asynchronous notifications

VariableCode defaultNotes
AI_RCA_STREAMAI_RCAAI root-cause work-queue stream.
AI_RCA_SUBJECTai.rca.jobsMust match API.
AI_RCA_CONSUMER_NAMEai-rca-workersDurable AI consumer.
NOTIFICATIONS_ENABLEDfalseStarts the worker notification consumer only when PostgreSQL is also configured.
NOTIFICATIONS_STREAMNOTIFICATIONSAsync notification work queue.
NOTIFICATIONS_SUBJECT_GLOBalerts.dispatch.>Subject filter shared with alerter.
NOTIFICATIONS_CONSUMER_NAMEnotifications-workerDurable dispatch consumer.

The worker uses the same LLM_* and SMTP_* variables documented on this page. Compose wires neither AI, notification, nor SMTP variables into the worker. Helm wires SMTP_* through its smtp values block; AI and notification-mode variables still require extraEnv.

Alerter and SMTP variables

VariableCode default / validationDescription
ALERT_STREAMALERTSAlert-event stream.
ALERT_SUBJECTalertsAlert-event subject.
ALERT_EVAL_INTERVAL_SECONDS30; positive integerCurrent alert-lifecycle evaluation cadence.
ALERTER_LATENCY_ANOMALY_ENABLEDtrue; booleanEnables latency-anomaly evaluation.
ALERT_REMINDER_INTERVAL_SECONDS3600; positive integerLegacy variable used only by the retired alert-evaluation path; current reminders use each tenant’s alert_reminder_seconds setting.
ALERT_GROUP_WINDOW_SECONDS60; positive integerLegacy grouping-window variable used only by the retired alert-evaluation path; currently unused.
ALERT_GROUP_MAX_CHILDREN5; positive integerLegacy grouped-child limit used only by the retired alert-evaluation path; currently unused. Current lifecycle handling uses group rollup.
ALERT_EMAIL_TOEmptyComma-separated fallback recipients for built-in email.
ALERTER_ASYNC_DISPATCHfalse; booleanPublishes channel dispatch jobs to NATS instead of sending synchronously.
NOTIFICATIONS_STREAMNOTIFICATIONSMust match worker.
NOTIFICATIONS_SUBJECT_GLOBalerts.dispatch.>Must match worker.

The SMTP_* variables are read identically by three services, and each one needs them for a different reason: the alerter delivers alert email from its evaluation loop, the worker delivers it when asynchronous dispatch is enabled, and the API serves POST /api/v1/alert-channels/{id}/test, which runs the same email plugin in-process. An install that sets SMTP only on the alerter delivers alerts correctly but fails every email channel test with mailer not configured. The Helm smtp values block renders the variables into all three at once; set it there rather than in a single service's extraEnv.

SMTP variableCode defaultImportant behavior
SMTP_HOSTEmptyRequired for usable built-in email delivery.
SMTP_PORT587Integer port.
SMTP_USERNAMEEmptyOptional SMTP authentication username.
SMTP_PASSWORDEmptySMTP authentication secret.
SMTP_FROMSMTP_USERNAME when emptyRequired effective sender address.
SMTP_FROM_NAMEProbara AlertsDisplay name on the From header. The envelope sender stays SMTP_FROM.
SMTP_USE_TLStrue; booleantrue selects direct implicit TLS, not STARTTLS. Verify the provider and port pairing.
APP_BASE_URLEmptyPublic origin of the operator UI. Adds an "open the monitor" button to alert email; omitted when unset. Read by the same three services.

Status-page and live-update variables

VariableCode default / validationDescription
STATUS_PAGE_BASE_URLEmptyPublic origin of the status service. Supplies the deep link in visitor push notifications; when empty, the notification opens the page via the service worker scope rather than a guessed host.
STATUS_PAGE_API_BASE_URLEmptyEnables the status service’s restricted API reverse proxy.
STATUS_PAGE_READ_TIMEOUT_SECONDS15Invalid or nonpositive input silently falls back to 15 seconds.
STATUS_PAGE_WRITE_TIMEOUT_SECONDS60Invalid or nonpositive input silently falls back to 60 seconds.
STATUS_PAGE_CACHE_TTL10s Go durationInvalid or nonpositive input falls back to 10 seconds.
STATUS_PAGE_PREVIEW_SECRETEmptyHMAC secret shared with API for one-hour preview tokens. With no secret, preview verification is not enforced.
STATUSPAGE_UPDATES_SUBJECTstatuspage.updatesCore NATS live-invalidation subject shared by API, scheduler, and status service. Also wakes the push sender early; delivery does not depend on it.
STATUS_PAGE_VAPID_PUBLIC_KEYEmptyVAPID application server key for visitor notifications. Published inside every rendered page, so it is not a secret. Generate with go run ./cmd/admin/gen_vapid_keys.
STATUS_PAGE_VAPID_PRIVATE_KEYEmptySigns the push JWT. A credential. Notifications are disabled unless both key halves are set; never generate per process, because replicas would disagree and a restart would invalidate every subscription.
STATUS_PAGE_VAPID_SUBJECTEmptymailto: or https: operator contact for the VAPID sub claim. Some push services reject a missing or malformed value.
STATUS_PAGE_PUSH_ENDPOINT_ALLOWLISTGoogle, Mozilla, Microsoft, Apple push hostsComma-separated host suffixes a stored push endpoint may use. This is an SSRF control; * disables it for a self-hosted push service.
STATUS_PAGE_PUSH_MAX_SUBSCRIPTIONS_PER_PAGE10000Cap on stored subscriptions per status page. Invalid or nonpositive input falls back to the default.
STATUS_PAGE_TRUSTED_PROXYfalseHonor X-Forwarded-For when rate-limiting push subscribes. Off by default because the header is client-settable.

The restricted proxy permits GET under /api/v1/monitors and PATCH under /api/v1/status-pages/…; it is not a general API proxy. Helm currently wires only basic status values and the status base URL, not the API proxy, cache, preview, timeout, or update-subject variables.

Frontend variables

VariableDefaultRuntime behavior
API_PROXY_TARGEThttp://localhost:8080Server-side destination for /api and downloadable agent-binary proxy routes.
NEXT_PUBLIC_API_URL/apiBrowser API base. Compiled into the Next.js client bundle.
NEXT_PUBLIC_STATUS_PAGE_URLEmptyStatus-page link origin; falls back to the current/relative origin or localhost during local use. Compiled into the client bundle.
NEXT_PUBLIC_DEBUG_INGEST_URLEmptyDeveloper-only debug timing sink. If set, monitor IDs and browser timing events are sent to it.
NODE_ENVDocker image sets productionNext.js runtime mode.
PORTDocker image sets 3000Next.js listener port.
HOSTNAMEDocker image sets 0.0.0.0Next.js bind address.

Collector agent settings

The host agent is probara-collector, an OpenTelemetry Collector distribution started as probara-collector --config <path>. Its generated configuration contains no secrets; credentials are supplied through the environment (systemd EnvironmentFile, launchd runner script, or the Windows service registry Environment value).

Environment variableDefaultDescription
PROBARA_API_KEYNone; requiredTenant write-scope API key sent as the Authorization: Bearer header.
PROBARA_AGENT_IDNone; requiredAgent monitor identifier sent as the X-Probara-Agent-Id header.

Maintenance, build, and test variables

VariableDefault / requirementCommand or scope
MIGRATIONS_PATH./migrationsgo run ./cmd/migrate; local workflow supplies ./shared/db/migrations.
ADMIN_USERNAMERequiredgo run ./cmd/admin administrator upsert.
ADMIN_PASSWORDRequiredgo run ./cmd/admin; do not expose in shell history in production.
BOOTSTRAP_DB_USERprobarascripts/bootstrap-local-db.sh.
OCB_VERSIONv0.159.0scripts/build-collector.sh; pinned OpenTelemetry Collector Builder version, must match collector/manifest.yaml.
BUILD_DIR./static/collectorOutput directory for downloadable collector binaries and checksums.txt.
GHCR_OWNERFalls back to GITHUB_REPOSITORY_OWNER; then requiredHelm OCI publication.
GITHUB_REPOSITORY_OWNERGitHub Actions context or shell valueFallback owner used by Helm OCI publication when GHCR_OWNER is empty.
GHCR_HELM_REPOoci://ghcr.io/<owner>/chartsHelm OCI destination.
SEMANTIC_RELEASE_TOKENRequired GitHub Actions secret for release workflowUsed as semantic-release, GHCR/Helm registry, GH_TOKEN, and GITHUB_TOKEN credential. Scope it to the repository/packages required by the workflow.
APIhttp://localhost:8080scripts/verify-auth.sh.
ADMIN_USERadminAuthentication verification helper.
ADMIN_PASSchange-meAuthentication verification helper only; never a production default.
VERIFY_SSO0Enable SSO checks in the auth verification helper.
API_URLhttp://localhost:8080Dependency-graph seed helper.
TENANT_IDAuto-select first tenant when supportedSeed/test helpers.
API_KEYPlaceholder in scripts/test-group-creation.shTest helper credential only; never use a production key in a disposable script shell history.
WRITE_PREVIEWEmptyTest-only flag that writes rendered status preview HTML.

GitHub’s PR_TITLE, PR_BODY, TARGET_BRANCH, GITHUB_OUTPUT, and GITHUB_STEP_SUMMARY variables are workflow-internal inputs for release-preview classification, not product runtime configuration. Docker build workflow values such as REGISTRY and IMAGE_PREFIX are likewise CI-owned defaults.

Deployment wiring summary

AreaDocker ComposeHelm chart
Core ports, DB, NATS, log levelWiredWired through values and generated connection URLs
Admin JWT and public API URLRequired interpolationRequired chart validation
OIDCDevelopment Dex-oriented variables wiredPrimary OIDC values and client Secret wired
Encryption keyringNot wiredBase key wired to API/worker/alerter, but not scheduler; rotation keys not exposed
AI fallbackNot wiredNot wired
SMTPNot wiredsmtp values block wired to API, worker, and alerter
Notification dispatch modeNot wiredNot wired
Scheduler result ingestCode defaults onlyCode defaults only
Scheduler purge and meshCode defaults onlyCode defaults only
Worker result stream and AI/notification queuesCode defaults onlyCode defaults only
Status cache, proxy, preview, timeout, update subjectPreview only; most defaultsNot wired
Browser artifact sharingShared volumeNo shared volume
Arbitrary extra environmentRequires editing ComposeNo extraEnv; requires chart template change