Configuration Reference
Every variable lives in .env.example at the repository root — copy it to .env (git-ignored) and fill in real values. No secret has a default; every service fails fast at startup if a required variable is missing. .env is never committed, and secrets are never hardcoded in source — libs/securelog also redacts password/secret/token/vault/ authorization fields from all structured logs regardless.
Database
Single engine for the whole stack — choose one option and set DB_HOST accordingly (don't mix them):
- Shared Zabbix DB server —
DB_HOST=<your Zabbix server IP>,DB_PORT=5432,DB_SSLMODE=require, then runops/init-db.shto create theseyalrun_*databases on that server. - Dedicated separate DB server — same as above but pointed at its own host.
- Containerized (default for staging/local dev) —
DB_HOST=postgres,DB_SSLMODE=disable,docker compose -f docker-compose.yml -f docker-compose.db.yml --profile postgres-db up -d.
| Variable | Purpose |
|---|---|
DB_ENGINE | postgres or mysql |
DB_HOST / DB_PORT / DB_USER / DB_PASSWORD | Connection details — single engine shared by seyalrun_identity and seyalrun_inventory |
DB_SSLMODE | disable / require / verify-full (postgres); disable / required (mysql) |
IDENTITY_DB_NAME, INVENTORY_DB_NAME, TERMINAL_DB_NAME, AUTOMATION_DB_NAME | Database names per service |
Redis
| Variable | Purpose |
|---|---|
REDIS_URL | Backs api-gateway's per-IP/user rate limiting. Use rediss:// for TLS if Redis isn't co-located. |
Auth / tokens
Client sessions are opaque, server-side (Redis) — not a JWT the browser can decode. JWT_SECRET/JWT_ALGORITHM sign only the short-lived Zabbix link-token and MFA credential-reveal token (identity-service internal use).
| Variable | Purpose |
|---|---|
JWT_SECRET | Link-token / credential-reveal token signing key |
JWT_ALGORITHM | Defaults to HS256 |
SESSION_IDLE_MINUTES | Session dies if idle this long (default 30) |
SESSION_ABSOLUTE_HOURS | Session dies at this age regardless of activity (default 8) |
SERVICE_JWT_SECRET | Service-to-service X-Service-Token signing key (all services) |
API_TOKEN_PEPPER | Extra pepper for hashing Personal Access Tokens |
Credential vault (inventory-service)
| Variable | Purpose |
|---|---|
ZA_VAULT_PASSWORD | AES-256-GCM credential encryption master key (≥ 32 chars) |
ZA_VAULT_SALT | Generate once: openssl rand -hex 16 |
SSH_KNOWN_HOSTS_PATH | SSH host-key verification for outbound connections (terminal + automation). Empty = no verification (logs a warning); set to a known_hosts file path to enforce strict host-key checking and mitigate MITM. |
Zabbix integration
| Variable | Purpose |
|---|---|
ZABBIX_API_URL / ZABBIX_API_TOKEN | Used for event acknowledgement |
ZABBIX_WEBHOOK_HMAC_SECRET | Required. HMAC key for the /webhook/zabbix receiver — it bypasses api-gateway, so this is its only auth. zabbix-integration-service refuses to start if unset. Generate: openssl rand -hex 32 |
ZABBIX_MODULE_SECRET | Only needed if the Zabbix frontend module is installed; leave blank otherwise (/auth/zbx-sso-init 503s). Must match module_secret in the module's own config.php exactly. |
ZABBIX_CONSOLE_URL | e.g. https://zabbix.example.com — included in job result messages |
api-gateway
| Variable | Purpose |
|---|---|
FRONTEND_ORIGIN | CORS allow-origin — must match the URL you browse to |
RATE_LIMIT_REQUESTS / RATE_LIMIT_WINDOW_SECONDS | Defaults 100 requests / 60 seconds |
edge-proxy (TLS termination — the only host-published service)
| Variable | Purpose |
|---|---|
TLS_CERT_PATH / TLS_KEY_PATH | Host paths to cert/key, bind-mounted (Let's Encrypt or internal CA) |
EDGE_HTTP_PORT / EDGE_HTTPS_PORT | Defaults 8080 / 8443 |
FRAME_ANCESTORS | Extra origins allowed to iframe SeyalRun. Header is always frame-ancestors 'self' <this> — leave blank for same-origin-only. To embed in Zabbix, set to the Zabbix origin as an unquoted host source, e.g. https://zabbix.example.com. Never set to * — that allows any site to frame the PAM console (clickjacking). |
Self-monitoring (agentless, HTTP)
No extra env vars beyond ZABBIX_WEBHOOK_HMAC_SECRET above — Zabbix polls GET https://<edge-host>:<EDGE_HTTPS_PORT>/webhook/zabbix/monitor with header X-Monitor-Token: <ZABBIX_WEBHOOK_HMAC_SECRET>. See Self-Monitoring.
Identity seed
| Variable | Purpose |
|---|---|
SEED_ADMIN_USERNAME | Default Admin |
SEED_ADMIN_PASSWORD | Leave blank to auto-generate; the seeded password is otherwise always seyalrun if left as the literal default — first login requires a password change before anything else works. |
Housekeeping / retention
| Variable | Purpose |
|---|---|
AUDIT_LOG_RETENTION_DAYS | Default 180 |
RECORDING_RETENTION_DAYS | Default 90 |
TERMINAL_RECORDING_MAX_FRAMES | Max frames retained per session recording in memory, oldest dropped first (default 20000) |
TERMINAL_POLICY_REFRESH_SECONDS | Seconds between command-filter/login-ACL cache refreshes in active sessions (default 60) |
Automation / job execution
| Variable | Purpose |
|---|---|
JOB_EXEC_TIMEOUT_SECONDS | Maximum wall-clock time per job run (default 3600) |
MAX_OUTPUT_LINES | output_lines cap per job run — oldest lines dropped when exceeded (default 500) |
Password strength / rotation
| Variable | Purpose |
|---|---|
WEAK_CREDENTIAL_THRESHOLD | zxcvbn score below this = weak (default 2) |
ROTATION_DEFAULT_DAYS | Default 90 |
Recording tiering
| Variable | Purpose |
|---|---|
RECORDING_TIER_AFTER_DAYS | Move local recordings to S3 after N days (default 7) |
Centralized log backend
Backend + secrets are managed at runtime in Admin → Log Backend, stored vault-encrypted in the database. These env vars are optional fallbacks, consumed only by the automation housekeeping ES-rollover job:
| Variable | Purpose |
|---|---|
ES_URL / ES_INDEX_PREFIX | Elasticsearch backend (prefix default seyalrun) |
S3_BUCKET / S3_REGION / S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY / S3_ENDPOINT_URL | S3-compatible backend; leave S3_ENDPOINT_URL blank for AWS, set it for MinIO/compatible |
Logging
| Variable | Purpose |
|---|---|
LOG_LEVEL | Default INFO |