Skip to content

Environment variables

All env vars are prefixed Z4J_ (brain-side) or read from the Z4J dict in framework settings (agent-side). Brain settings map onto fields in z4j_brain.settings.Settings; the prefix is dropped and the name lowercased (e.g. Z4J_EVENT_RETENTION_DAYS -> settings.event_retention_days).

This page lists every Z4J_* variable the brain reads. Most operators set only the required four plus a handful from the Database, Retention, and Metrics sections; the rest are exposed for fine-tuning under sustained load or unusual deployments.

VariableDescription
Z4J_DATABASE_URLPostgreSQL connection string (postgresql+asyncpg://user:pw@host/db).
Z4J_SECRETMaster HMAC signing key. Drives the per-project frame HMAC, the audit-log row HMAC, and the session-cookie signer’s master derivation. 64 hex chars recommended.
Z4J_SESSION_SECRETIndependent secret for user-session cookies. Rotating it invalidates active sessions.
Z4J_PUBLIC_URLFull externally reachable base URL with scheme (https://z4j.example.com). Validated: no whitespace, no userinfo, http(s) only.
VariableDefaultDescription
Z4J_PREVIOUS_SECRETS-Comma-separated previous Z4J_SECRET values still accepted while verifying older audit rows / frames during rotation. Writes always use the new Z4J_SECRET. Empty = no rotation in progress.
Z4J_PREVIOUS_SESSION_SECRETS-Comma-separated previous session secrets still accepted while verifying older cookies during rotation.
VariableDefaultDescription
Z4J_DATABASE_STATEMENT_CACHE_SIZE50Per-connection asyncpg prepared-statement cache cap. 0 disables. See Brain memory tuning.
Z4J_DATABASE_MAX_INACTIVE_CONNECTION_LIFETIME_SECONDS60Seconds before an idle asyncpg connection is closed and reopened. Maps to SQLAlchemy’s pool_recycle.
Z4J_AUTO_MIGRATEtrueRun Alembic head migrations on brain boot. Set to false for orchestrators that run migrations as a separate step.
Z4J_REQUIRE_DB_SSLtrueRefuse Postgres URLs that disable SSL (auto-relaxed when the URL points at a loopback host).
Z4J_DB_STATEMENT_TIMEOUT_MS10000Postgres statement_timeout (milliseconds). Caps any single query.
Z4J_DB_LOCK_TIMEOUT_MS3000Postgres lock_timeout (milliseconds). Caps how long a transaction waits for a row lock.
Z4J_DB_IDLE_IN_TX_TIMEOUT_MS30000Postgres idle_in_transaction_session_timeout (milliseconds).
Z4J_ASYNCPG_CONNECT_TIMEOUT10.0Seconds before an asyncpg connect attempt times out.
Z4J_ASYNCPG_CLOSE_TIMEOUT5.0Seconds before an asyncpg close call times out.
Z4J_WAL_CHECKPOINT_INTERVAL_SECONDS300SQLite-only PRAGMA wal_checkpoint(TRUNCATE) cadence. Ignored on Postgres.
VariableDefaultDescription
Z4J_PASSWORD_MIN_LENGTH8Minimum password length.
Z4J_ARGON2_TIME_COST3argon2id time cost.
Z4J_ARGON2_MEMORY_COST65536argon2id memory (KiB, 64 MiB default).
Z4J_ARGON2_PARALLELISM4argon2id threads.
VariableDefaultDescription
Z4J_SESSION_ABSOLUTE_LIFETIME_SECONDS604800Hard cap on a session’s age (default 7 days). Sessions are rejected past this regardless of activity.
Z4J_SESSION_IDLE_TIMEOUT_SECONDS1800Sliding idle timeout (default 30 minutes). Sessions whose last_seen_at is older than this are rejected.
Z4J_SESSION_COOKIE_SAMESITElaxSameSite attribute on the session cookie. lax or strict.
Z4J_SESSION_PIN_USER_AGENTfalseIf true, the resolved client User-Agent at session issue time is enforced on every subsequent request. Off by default; too many false positives on mobile networks.
Z4J_LOGIN_LOCKOUT_THRESHOLD10Failed login attempts on a single account before lockout.
Z4J_LOGIN_LOCKOUT_DURATION_SECONDS900Lockout duration after threshold exceeded.
Z4J_LOGIN_BACKOFF_BASE_SECONDS0.5Base per-failure backoff applied to the login response.
Z4J_LOGIN_BACKOFF_MAX_SECONDS5.0Cap on the per-failure backoff.
Z4J_LOGIN_MIN_DURATION_MS300Minimum total response time for /auth/login (success or failure). Held by asyncio.sleep so timing variance cannot leak whether the account exists.
Z4J_LOG_LOGIN_EMAILfalseLog the attempted email on failed logins. Off by default (PII consideration).
VariableDefaultDescription
Z4J_RECONCILIATION_SWEEP_SECONDS300Seconds between reconciliation passes that compare in-flight tasks against engine result backends.
Z4J_RECONCILIATION_STALE_THRESHOLD_SECONDS900Minimum age before a task in started state becomes eligible for reconciliation.
VariableDefaultDescription
Z4J_EVENT_RETENTION_DAYS30Days raw events rows live before the retention worker drops their partition.
Z4J_AUDIT_RETENTION_DAYS90Days audit_log rows live before the retention worker prunes them.
Z4J_AUDIT_RETENTION_SWEEP_INTERVAL_SECONDS3600Seconds between audit retention sweeps (default 1 hour).
Z4J_AUDIT_RETENTION_SWEEP_BATCH_SIZE5000Rows pruned per database round-trip inside one sweep pass.
Z4J_AUDIT_RETENTION_SWEEP_MAX_PER_PASS200000Hard cap on rows deleted in a single sweep pass. Sweeps stop and resume on the next interval if the cap is hit.
VariableDefaultDescription
Z4J_METRICS_AUTH_TOKEN- (auto-minted)Bearer token required by /metrics. Operators may provide one explicitly via env or ~/.z4j/secret.env; if absent and Z4J_METRICS_PUBLIC is unset, z4j serve auto-mints one and writes it to ~/.z4j/secret.env. Run z4j metrics-token to print or rotate.
Z4J_METRICS_PUBLICfalseSet to 1 to leave /metrics open. Use only when the endpoint is firewalled or behind an authenticated proxy.
Z4J_METRICS_ENABLEDtrueSet to false to skip mounting the /metrics route entirely (very rare; use the auth-token instead).
VariableDefaultDescription
Z4J_BOOTSTRAP_ADMIN_EMAIL-Skip the first-boot setup URL and auto-provision an admin with this email. Read once at boot.
Z4J_BOOTSTRAP_ADMIN_PASSWORD-Required when Z4J_BOOTSTRAP_ADMIN_EMAIL is set. Eagerly popped from os.environ after use.
Z4J_FIRST_BOOT_TOKEN_TTL_SECONDS900Validity window for the one-time setup token (default 15 minutes).
Z4J_FIRST_BOOT_ATTEMPTS_PER_IP30Sliding-window cap on setup-token verification attempts per IP per 15 minutes.
VariableDefaultDescription
Z4J_MFA_ENFORCE_FOR_ADMINSfalseBlock sign-in for un-enrolled admins past the grace window.
Z4J_MFA_ENFORCE_FOR_ALLfalseSame for every user. Stricter superset of the admins-only flag.
Z4J_MFA_ENROLLMENT_GRACE_DAYS7Days an enforcement-targeted user has to enroll before sign-in is blocked. Range 1..90.
Z4J_MFA_RECOVERY_CODE_COUNT10Single-use recovery codes minted at enrollment. Range 5..50.
Z4J_MFA_VERIFICATION_TTL_SECONDS900How long a successful MFA verify counts as fresh for the sensitive-action gate (default 15 min).
Z4J_MFA_REMEMBER_DEVICE_DAYS30Lifetime of the z4j_mfa_trust “remember this device” cookie. Hard upper bound 90.
Z4J_MFA_VERIFICATION_RATE_PER_MIN10Per-IP cap on /auth/mfa/verify attempts per minute. Tighter than login because the endpoint is a TOTP brute-force target.

See Multi-factor authentication for the full design + threat model.

VariableDefaultDescription
Z4J_NOTIFICATIONS_WEBHOOK_ALLOW_HTTPfalseAllow http:// webhook URLs. Default refuses plaintext at both config-validation and dispatch time.
VariableDefaultDescription
Z4J_AGENT_OFFLINE_TIMEOUT_SECONDS30Heartbeats older than this mark the agent offline in the dashboard.
Z4J_AGENT_HEALTH_SWEEP_SECONDS10Cadence for the agent health-check sweep.
Z4J_AGENT_STALE_PRUNE_DAYS30Agents offline for longer than this are pruned from the dashboard listings. The agent row is soft-removed; audit references keep their FK.
VariableDefaultDescription
Z4J_WS_IDLE_TIMEOUT_SECONDS90Per-connection idle timeout for /ws (agent) and /ws/dashboard.
Z4J_WS_INGEST_QUEUE_MAXSIZE2000Bounded per-connection ingest queue. Decouples app-level frame dispatch from the WS recv loop so PING/PONG keeps flowing.
Z4J_WS_MAX_FRAME_BYTES1048576Maximum inbound WebSocket frame size (1 MiB).
Z4J_WS_PER_AGENT_CONCURRENCY_CAP64Maximum concurrent worker connections per agent_id (worker-first protocol).

The brain’s BrainRegistry routes commands to agent connections across replicas. The default postgres_notify backend uses Postgres LISTEN/NOTIFY; SQLite forces local automatically.

VariableDefaultDescription
Z4J_REGISTRY_BACKENDpostgres_notifypostgres_notify or local. SQLite forces local.
Z4J_REGISTRY_LISTENER_HEARTBEAT_SECONDS10Self-NOTIFY heartbeat for the watchdog on the LISTEN connection.
Z4J_REGISTRY_LISTENER_HEARTBEAT_TIMEOUT_SECONDS25Timeout before the watchdog reconnects the LISTEN connection.
Z4J_REGISTRY_LISTENER_MAX_AGE_SECONDS900Hard-recycle interval for the LISTEN connection.
Z4J_REGISTRY_RECONCILE_INTERVAL_SECONDS30Poll cadence for pending commands targeting an agent this replica owns.

These are app-level caps; the per-endpoint per-IP buckets in authentication and rate-limits layer on top.

VariableDefaultDescription
Z4J_MAX_PAYLOAD_SIZE_BYTES8192Maximum REST request body size. Larger requests return 413.
Z4J_TASKS_EXPORT_MAX_ROWS50000Upper bound on rows fetched by task / audit export endpoints. Beyond this, the call returns a validation error pointing operators at narrower filters.
Z4J_RATELIMIT_COMMANDS_PER_MINUTE100Per-project upper bound on command issuance.
Z4J_RATELIMIT_EVENTS_PER_SECOND10000Per-project upper bound on event ingestion.
Z4J_ADMIN_PROJECT_LIST_CAP500Upper bound on admin project-listing endpoints.
Z4J_REQUEST_TIMEOUT_SECONDS30Per-request handler wall-clock budget.
Z4J_REST_DEFAULT_PAGE_SIZE50Default page size on REST list endpoints.
Z4J_REST_MAX_PAGE_SIZE500Maximum page size on REST list endpoints.
VariableDefaultDescription
Z4J_ALLOWED_HOSTS[]Host-header allow-list. Production deployments must populate this. Use z4j allowed-hosts add for live management. See allowed hosts.
Z4J_CORS_ORIGINS[]Allowed CORS origins for the dashboard. JSON array of full origins.
Z4J_CORS_ALLOW_CREDENTIALStrueAllow credentials on CORS requests.
Z4J_TRUSTED_PROXIES[]CIDR list of reverse-proxy IPs whose X-Forwarded-For the brain should trust. Empty list means trust no proxy.
Z4J_HSTS_MAX_AGE_SECONDS31536000HSTS max-age (default 1 year). Emitted only in production over HTTPS.
Z4J_HSTS_INCLUDE_SUBDOMAINStrueAppend includeSubDomains to the HSTS header.
Z4J_ALLOW_HTTP_PUBLIC_URLfalseTest/dev escape hatch: permit a plaintext http:// Z4J_PUBLIC_URL. Never set in production.
VariableDefaultDescription
Z4J_BIND_HOST0.0.0.0ASGI bind host.
Z4J_BIND_PORT7700ASGI bind port.
Z4J_ENVIRONMENTproductionFree-form environment label surfaced in logs and on the dashboard. Affects nothing else.
Z4J_LOG_JSONtrueEmit logs as JSON (true) or human-readable console output (false).
Z4J_LOG_LEVELINFOStdlib logging level.
Z4J_VERSION_CHECK_URL(canonical GitHub raw URL)Source URL for the dashboard “Check for updates” button. Override to point at a private mirror in restricted environments.
VariableDefaultDescription
Z4J_COMMAND_TIMEOUT_SECONDS60Age threshold past which a dispatched command is marked timed-out. Surfaces as 504 command_timeout to API callers.
Z4J_COMMAND_TIMEOUT_SWEEP_SECONDS5Cadence for the command-timeout sweeper worker.

The brain accepts mTLS gRPC connections from z4j-scheduler instances. Disabled by default.

VariableDefaultDescription
Z4J_SCHEDULER_GRPC_ENABLEDfalseAccept mTLS gRPC connections from z4j-scheduler.
Z4J_SCHEDULER_GRPC_BIND_HOST0.0.0.0Bind interface for the scheduler gRPC server.
Z4J_SCHEDULER_GRPC_BIND_PORT7701Bind port for the scheduler gRPC server.
Z4J_SCHEDULER_GRPC_ALLOWED_CNS[]JSON array of allow-listed scheduler client CNs.
Z4J_SCHEDULER_GRPC_REQUIRE_ALLOWLISTfalseFail closed if _ALLOWED_CNS is missing instead of falling back to trust-the-CA.
Z4J_SCHEDULER_GRPC_CN_PROJECT_BINDINGS{}JSON object mapping scheduler CN to allowed project list.
Z4J_SCHEDULER_GRPC_TLS_CERT-Brain’s gRPC server certificate (PEM path).
Z4J_SCHEDULER_GRPC_TLS_KEY-Brain’s gRPC server private key (PEM path).
Z4J_SCHEDULER_GRPC_TLS_CA-CA bundle for validating incoming scheduler client certs.
Z4J_SCHEDULER_GRPC_INSECUREfalseDev/test only: bind the scheduler gRPC port without TLS. Refuses to start in production.
Z4J_SCHEDULER_GRPC_GRACE_SECONDS5.0Graceful drain window on shutdown for in-flight RPCs.
Z4J_SCHEDULER_GRPC_FIRE_RATE_LIMIT_ENABLEDtrueEnable the per-cert rate limit on FireSchedule.
Z4J_SCHEDULER_GRPC_FIRE_RATE_PER_SECOND10.0Sustained refill rate (tokens / sec) for the per-cert fire-rate limit.
Z4J_SCHEDULER_GRPC_FIRE_RATE_CAPACITY600.0Maximum burst size for the per-cert fire-rate limit.
Z4J_SCHEDULER_GRPC_WATCH_MAX_CONCURRENT64Hard cap on concurrent WatchSchedules streams per brain process.
Z4J_SCHEDULER_GRPC_WATCH_MAX_PER_CERT4Per-CN cap on concurrent WatchSchedules streams.
Z4J_SCHEDULER_GRPC_WATCH_POLL_SECONDS2.0Poll cadence for the watch-stream backend.
Z4J_SCHEDULER_INFO_URLS[]HTTP URLs of scheduler instances for the dashboard’s fleet-status page.

When the brain needs to push a schedule trigger to z4j-scheduler, it dials an outbound gRPC channel. Without Z4J_SCHEDULER_TRIGGER_URL set, the brain falls back to its in-process scheduler path and the TLS variables are ignored.

VariableDefaultDescription
Z4J_SCHEDULER_TRIGGER_URL-host:port of the scheduler’s TriggerSchedule listener.
Z4J_SCHEDULER_TRIGGER_TLS_CERT-Path to the brain’s client certificate.
Z4J_SCHEDULER_TRIGGER_TLS_KEY-Path to the brain’s client key.
Z4J_SCHEDULER_TRIGGER_TLS_CA-Path to the CA bundle the brain uses to verify the scheduler’s server cert.

For homelab / single-instance deployments the brain can spawn z4j-scheduler as a supervised subprocess. See z4j-scheduler.

VariableDefaultDescription
Z4J_EMBEDDED_SCHEDULERfalseSpawn z4j-scheduler as a supervised subprocess inside the brain lifespan.
Z4J_EMBEDDED_SCHEDULER_ARGV["serve"]Subprocess argv after the implicit [sys.executable, "-m", "z4j_scheduler"] prefix.
Z4J_EMBEDDED_SCHEDULER_PKI_DIR~/.z4j/embedded-pki/Directory for auto-minted loopback mTLS PKI.
Z4J_EMBEDDED_SCHEDULER_RESTART_MAX_ATTEMPTS10Maximum auto-restart attempts before the supervisor gives up.
Z4J_EMBEDDED_SCHEDULER_RESTART_BACKOFF_SECONDS2.0Initial backoff between restart attempts (doubles up to a 60s cap).
Z4J_EMBEDDED_SCHEDULER_SHUTDOWN_GRACE_SECONDS10.0Grace window for SIGTERM before the supervisor sends SIGKILL.
VariableDefaultDescription
Z4J_SCHEDULE_FIRES_RETENTION_DAYS30Days schedule_fires rows live before the periodic prune.
Z4J_PENDING_FIRES_RETENTION_DAYS7Days buffered fires can stay pending before being dropped.
Z4J_PENDING_FIRES_REPLAY_INTERVAL_SECONDS10Cadence for the buffered-fire replay worker.
Z4J_SCHEDULE_CIRCUIT_BREAKER_THRESHOLD5Consecutive failed fires before the schedule is auto-disabled.
Z4J_SCHEDULE_CIRCUIT_BREAKER_INTERVAL_SECONDS60Sweep cadence for the schedule circuit-breaker worker.

The following fields exist on Settings but are infrastructure or test-only and should not be set by operators:

  • Z4J_DASHBOARD_DIST — filesystem path to built dashboard assets (set by the container image).
  • Z4J_DISABLE_SPA_FALLBACK — unit-test fixture flag.

Set in your framework’s config dict (e.g. Django settings.Z4J) or as the matching Z4J_* env var:

KeyRequiredDefaultDescription
brain_urlyes-WebSocket URL of z4j
tokenyes-Agent bearer token
hmac_secretyes-Per-project HMAC secret returned at agent-mint time
project_idno"default"Project slug
agent_nameno$HOSTNAMEDisplay name
buffer_sizeno1000Event buffer cap
heartbeat_intervalno10Seconds between heartbeats
reconnect_backoff_maxno60Max backoff on reconnect

Env vars override everything. File-based settings (~/.z4j/config.env) can supplement env vars but not replace them. Explicit keyword arguments to the framework adapter win over both.