Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration reference

Every environment variable SecureScan reads, what it controls, and its default. All variables are optional unless flagged otherwise.

Authentication

VariableDefaultDescription
SECURESCAN_API_KEY(unset)Legacy single-shared-key auth. Treated as a synthetic principal with all scopes. When unset and no DB keys exist, runs in dev mode.
SECURESCAN_AUTH_REQUIRED0When 1, backend exits with code 2 at startup if no credentials configured. Required for hardened deploys.
SECURESCAN_EVENT_TOKEN_SECRET(auto)HMAC signing secret for SSE event tokens. Required when AUTH_REQUIRED=1. Ephemeral random in dev mode.

Authentication overview, API keys, SSE event tokens.

Rate limiting

VariableDefaultDescription
SECURESCAN_RATE_LIMIT_PER_MIN60Sustained requests per minute on POST /scans (per principal / IP).
SECURESCAN_RATE_LIMIT_BURST10Burst capacity above the sustained rate.
SECURESCAN_RATE_LIMIT_ENABLEDtrueSet to false to disable. Only do this if you have a smarter rate limiter in front.

Rate limits.

Logging

VariableDefaultDescription
SECURESCAN_LOG_LEVELINFODEBUG / INFO / WARNING / ERROR.
SECURESCAN_LOG_FORMATtext (or json if in container)text for dev TTY; json for container / aggregator-friendly.
SECURESCAN_IN_CONTAINER0When 1, default LOG_FORMAT flips to json.

Each request emits one structured line on securescan.request with request_id, method, path, status, latency_ms. Scan lifecycle events go on securescan.scan with event + per-event fields.

CORS / network

VariableDefaultDescription
SECURESCAN_CORS_ORIGINSlocalhost:3000,127.0.0.1:3000,localhost:3003,127.0.0.1:3003Comma-separated CORS origins.

When the frontend and backend are on different hosts, set this to the frontend's origin(s) so the browser doesn't get CORS-blocked.

Frontend

VariableDefaultDescription
NEXT_PUBLIC_SECURESCAN_API_KEY(unset)API key the dashboard injects on every request. Baked into the build.
NEXT_PUBLIC_SECURESCAN_API_URLhttp://localhost:8000Backend URL the dashboard talks to.

Both are NEXT_PUBLIC_* (Next.js convention) so they end up in the browser bundle. Use a read scope key, not admin — see Production checklist.

Scanner-specific

VariableDefaultDescription
SECURESCAN_ZAP_ADDRESShttp://127.0.0.1:8090URL of the ZAP daemon for the zap scanner.
SECURESCAN_ZAP_API_KEY(unset)API key the ZAP daemon expects.
SECURESCAN_GROQ_API_KEY(unset)Groq API key for AI enrichment. AI is auto-disabled in CI (CI=true).

These can — and should — live in ~/.config/securescan/.env rather than the shell environment, so they persist across reboots. See Local config (.env).

CI determinism

VariableDefaultDescription
CI(unset)Set to true by GitHub Actions / GitLab CI / etc. SecureScan auto-disables AI enrichment when set.
SECURESCAN_FAKE_NOW(unset)Pin the only time-derived field in output. Set in tests / CI replays for byte-identical output.

How scans work → Determinism.

Database

VariableDefaultDescription
SECURESCAN_DB_PATH~/.securescan/scans.dbSQLite DB file path. Persists scans, findings, triage state, keys, webhooks, notifications.

In containers, mount a volume at this path. See Docker.

Examples

Minimum production env

export SECURESCAN_AUTH_REQUIRED=1
export SECURESCAN_EVENT_TOKEN_SECRET="$(openssl rand -hex 32)"
export SECURESCAN_API_KEY="$(openssl rand -hex 32)"   # break-glass
export SECURESCAN_LOG_FORMAT=json

Then issue scoped DB keys for actual consumers (CI, dashboard) via the API; reserve the env-var key for emergencies.

Container env-file

# /etc/securescan/env
SECURESCAN_AUTH_REQUIRED=1
SECURESCAN_EVENT_TOKEN_SECRET=replace-me-with-openssl-rand-hex-32
SECURESCAN_LOG_FORMAT=json
SECURESCAN_IN_CONTAINER=1
SECURESCAN_RATE_LIMIT_PER_MIN=120
SECURESCAN_RATE_LIMIT_BURST=20
SECURESCAN_CORS_ORIGINS=https://securescan.example.com
docker run --env-file /etc/securescan/env \
  -v securescan-data:/data \
  ghcr.io/metbcy/securescan:v0.11.0 \
  serve --host 0.0.0.0 --port 8000 --workers 1

Tuning rate limits for a CI fleet

A team with 30 CI runners hitting the same key would saturate the default 60/min. Bump it:

export SECURESCAN_RATE_LIMIT_PER_MIN=300
export SECURESCAN_RATE_LIMIT_BURST=30

Or — better — issue one DB key per runner so they have isolated buckets.

Source

Next