Configuration#

Every runtime setting is an environment variable. The binary reads them at startup; there is no config file. Defaults are tuned for a one-command local evaluation (single-node CockroachDB, auth off) — review the production-relevant rows before exposing rackattack (see Security & auth, Deployment, and the production design in docs/production-deployment.md).

Booleans accept 1 / true / yes / on (and their negatives).

Server & database#

EnvMeaningDefault
DATABASE_URLCockroachDB (Postgres-compatible) connection string. Used by every subcommand.postgres://root@localhost:26257/rackattack?sslmode=disable
GRPC_ADDRListen address for the gRPC server (serve).:8080
HTTP_ADDRListen address for the HTTP server (serve) — REST gateway, GraphQL, /metrics, and /audit/*.:8081
DB_MAX_CONNSMax size of the pgx connection pool — the knob to tune under concurrent load. Can also be set with a pool_max_conns query param on DATABASE_URL.pgx default: max(4, GOMAXPROCS)
DB_TLS_ROOT_CERTPath to the CA certificate (PEM) used to verify the CockroachDB server cert under sslmode=verify-full, when you’d rather not put sslrootcert= in DATABASE_URL (e.g. a mounted k8s Secret). Ignored if the URL already sets sslrootcert.unset
SHUTDOWN_GRACE_PERIODOn SIGTERM/SIGINT, serve stops accepting new work and drains in-flight gRPC RPCs and HTTP requests within this budget (Go duration) before exiting. Keep it under the pod’s terminationGracePeriodSeconds (30s).25s
RACKATTACK_ENVSet to production (or prod) to enable the production guardrail: serve refuses to boot with edge auth disabled, or a DATABASE_URL that doesn’t verify TLS (anything other than sslmode=verify-full or verify-cadisable/allow/prefer/require/unset all fail), failing fast with a clear error. Production mode also disables the GraphQL playground and gRPC reflection. Any other value (or unset) is development mode.unset (development)
HTTP_MAX_BODY_BYTESMaximum request-body size (bytes) accepted on the HTTP app surface (GraphQL, REST, bulk upserts); oversized requests are rejected. Raise it if you bulk-import very large fleets.8388608 (8 MiB)

In production, DATABASE_URL should use sslmode=verify-full against a secure CockroachDB and a non-root, least-privilege SQL user — not the insecure local default. Supply the cluster CA via sslrootcert= in the URL or DB_TLS_ROOT_CERT; with RACKATTACK_ENV=production the server refuses to boot on sslmode=disable.

TLS is negotiated by pgx from the connection string; the test suite covers the config wiring (a verify-full URL yields a verifying TLS config; DB_TLS_ROOT_CERT loads the CA), but a live verify-full handshake requires a TLS-enabled CockroachDB. To validate end-to-end, point DATABASE_URL at your secure cluster and confirm /readyz returns ready (it does a real DB round-trip).

On startup serve logs an effective config summary (addresses, redacted database URL, sslmode, auth method, cache backend, shutdown grace) so you can confirm at a glance what the process actually booted with. Secrets (DB password, HS256 key) are never logged.

Cache#

Read-through cache over the hot read RPCs; flushed on every mutation. See Caching.

EnvMeaningDefault
CACHE_ENABLEDTurn the read cache on/off.true
CACHE_TTLEntry time-to-live (Go duration, e.g. 30s, 1m). Bounds staleness from out-of-band writes.30s
CACHE_SIZEIn-process LRU capacity (entries).1024
REDIS_ADDRhost:6379. When set, all replicas share one Redis cache (so invalidation is global). Required for correct cross-replica invalidation when running more than one replica.unset (in-process LRU)

Authentication & authorization#

OIDC/JWT bearer validation + role-based authz at every transport edge. See Security & auth. When AUTH_ENABLED=true, exactly one key source (AUTH_JWKS_URL or AUTH_HS256_SECRET) must be set or serve refuses to start.

EnvMeaningDefault
AUTH_ENABLEDEnforce auth. When false, the edges inject a dev principal with the writer role and the whole surface is open (no token needed).false
AUTH_JWKS_URLOIDC JWKS endpoint for asymmetric (RS/ES) tokens.unset
AUTH_HS256_SECRETSymmetric HS256 key (use instead of JWKS).unset
AUTH_ISSUERExpected token iss; checked when set.unset
AUTH_AUDIENCEExpected token aud; checked when set.unset
AUTH_ROLES_CLAIMClaim holding the principal’s roles; dotted for nested (e.g. realm_access.roles).roles
AUTH_WRITER_ROLESComma-separated roles permitted to mutate; reads are open to any authenticated principal.writer,admin
AUTH_OIDC_ISSUERIdP discovery base for the browser login flow (web UI); falls back to AUTH_ISSUER.unset
AUTH_OIDC_CLIENT_ID / AUTH_OIDC_CLIENT_SECRETOAuth client for the browser authorization-code flow.unset
AUTH_OIDC_REDIRECT_URLBrowser login callback, e.g. https://host/auth/callback (must match the IdP registration).unset
AUTH_OIDC_SCOPESScopes requested at login.openid,profile,email
AUTH_SESSION_SECRETSigns the browser session cookie; required when the AUTH_OIDC_* flow is configured.unset
AUTH_SESSION_TTLBrowser session lifetime before re-auth.12h
AUTH_OIDC_POST_LOGOUT_REDIRECT_URIAbsolute URL the IdP returns to after RP-initiated logout (must be IdP-registered).unset

The browser login flow is described in Security & auth → “Browser login”.

Audit / CDC#

Mutations are captured to audit_log via CockroachDB change-data-capture. See Audit & CDC.

EnvMeaningDefault
AUDIT_CHANGEFEEDRun the in-process core changefeed (license-free; one feed per process). Leave off when using the native webhook sink, and off at >1 replica (it would double-record).false
AUDIT_WEBHOOK_SECRETShared secret guarding the /audit/webhook sink. When set, the endpoint requires Authorization: Bearer <secret> and rejects everything else with 401 — configure the changefeed with WITH webhook_auth_header = 'Bearer <secret>'. Leave unset only for a network-restricted dev endpoint.unset (open)

Telemetry#

OpenTelemetry tracing across RPC → query → render. See Observability.

EnvMeaningDefault
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collector endpoint (e.g. collector:4317). Tracing is a no-op when unset.unset (off)
OTEL_EXPORTER_OTLP_INSECUREUse plaintext OTLP (for a local collector).false

Standard OTLP SDK environment variables are honored by the exporter; the service name is fixed to rackattack.

Test / contributor-only#

These affect tests, not the running service: RACKATTACK_TEST_DB (DB URL for integration tests), RACKATTACK_UPDATE_GOLDEN (rewrite golden SVGs), and the SCALE_* knobs for the load harness. See the contributing guide.