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

Production checklist

Go through this before a deployment carries real users. Each item links to the page that explains it. Run a release, or a commit you have reviewed, and record which one (by image digest) you run.

Secrets and keys

  • The master key is generated once, stored in a secret manager, and backed up apart from the database. openssl rand -hex 32; supply it as MASTER_KEY_FILE (a mounted secret) rather than an environment variable where you can. Every node gets the same key. A database backup without its key cannot decrypt signing keys, MFA secrets or provider credentials, and anyone holding both has everything, so the key and the backups never sit in the same place. Signing keys and the master key, Container image
  • You know how to rotate the master key (MASTER_KEY_VERSION, MASTER_KEY_PREVIOUS, ridm-api rotate-master-key) and have done it once in a test environment. Rotating keys
  • Signing key rotation is set per tenant to the interval your relying parties can follow; the key_rotation job applies it hourly. Rotating keys
  • Database and Valkey passwords are not the compose defaults (ridm, ridm_migrator, ridm_app). docker-compose

URLs, TLS and proxies

  • PUBLIC_URL is the final https URL. Every issuer derives from it; changing it later breaks every relying party. TLS and reverse proxies
  • TLS terminates at your proxy, or natively with TLS_CERT and TLS_KEY, and plain http redirects to https. TLS and reverse proxies
  • COOKIE_SECURE is true (the default). Sign-in then works only over https, which is the point. TLS and reverse proxies
  • TRUSTED_PROXIES lists exactly your proxy tier: empty behind a proxy makes every user one address; too wide lets callers forge theirs. TLS and reverse proxies
  • The UI is served from the same origin as the API: the image’s embedded UI (UI_URL unset), or ui/out on the same host with the framing headers and HSTS added by the static server. Deployment overview, TLS and reverse proxies
  • Custom domains have DNS, a certificate and a proxy route before a tenant turns one on. Custom domains

Exposure

  • DOCS_ENABLED is off (the default), so Swagger UI is not served at /docs. /openapi.json is served either way; it describes the API and holds no data. Server configuration
  • /.well-known/security.txt names your security contact (SECURITY_CONTACT, or your own document in SECURITY_TXT_FILE); it answers 404 until you set one. Server configuration
  • /metrics is protected: METRICS_TOKEN is set, or the path is not routed from the internet, or both. Observability
  • Postgres and Valkey are not reachable from the internet, and the compose file’s published ports are removed on any shared host. Postgres and Valkey, docker-compose
  • Outbound traffic is allowed only where needed: mail, SMS webhook, webhook receivers, upstream identity providers, the breached-password API (or BREACH_CHECK_URL=off), audit sink, collector. rIDM refuses private and loopback destinations for the URLs tenant administrators choose, but an egress firewall is still the boundary. Deployment overview

Database

  • The API connects as the DML-only app role and migrations run separately as the migrator. MIGRATE_ON_START=true is harmless under that role once the schema is current, but never give the server the migrator’s credentials so that it can migrate itself. Postgres and Valkey, Container image
  • The app role can execute audit_ensure_partitions. The migration grants it to roles that already had INSERT on the audit log; an app role created later needs the grant by hand. Postgres and Valkey
  • Pool sizes fit max_connections across all nodes (and the replica pool, if any). Postgres and Valkey
  • Valkey has enough memory never to evict, and append-only persistence on. Eviction signs users out and forgets revoked access tokens. Postgres and Valkey

First administrator and tenants

  • The first global administrator is bootstrapped and has changed the initial password (forced at first sign-in unless --no-must-change was used). Remove BOOTSTRAP_ADMIN_EMAIL and BOOTSTRAP_ADMIN_PASSWORD from the environment afterwards (or empty secrets/bootstrap_admin_password in the production compose stack). Production with docker-compose, Administrator access
  • Administrators use a second factor. MFA policy
  • Email works: SMTP_HOST, SMTP_FROM (required once SMTP_HOST is set), SMTP_SECURITY (starttls by default), or per-tenant settings. Send a test invitation or password reset. Email, SMS and templates

Abuse controls

  • Rate limits are on (RATE_LIMITS=true, the default) and RATE_LIMIT_IP_PER_MINUTE suits your traffic; tenant ceilings are reviewed. Never carry RATE_LIMITS=false over from a load test. Rate limits, IP rules and CAPTCHA
  • Volume attacks are absorbed in front of rIDM, by a CDN, WAF or edge proxy. rIDM limits what one caller can do; it cannot absorb a flood.
  • Clocks are synchronised (NTP) on every node. Token expiry, TOTP and DPoP proofs depend on it.

Operations

  • Liveness probes /healthz, readiness and load-balancer checks probe /readyz. Container image
  • Logs are JSON (LOG_FORMAT=json) and collected, with alerts on the lines listed in Observability.
  • Metrics are scraped from every node, with alerts on job errors, audit sink drops and failures, dead-lettered webhooks and readiness. Observability
  • Audit rows are shipped off the host with AUDIT_SINK_URL, if your policy requires a copy an intruder on the host cannot alter. Observability
  • RETENTION_DAYS and each tenant’s audit retention match your policy. Scaling and performance
  • Postgres is backed up, encrypted and access-controlled, and a restore has been tested with the master key, into a scratch database, as far as issuing a token. A logical dump needs a role that bypasses row level security. Backup and restore
  • The master key has a second, offline copy, and every older generation is kept for as long as a backup encrypted under it. Backup and restore
  • You know how you will upgrade and roll back: migrate first, roll second, a backup before every upgrade. Upgrading
  • Load has been tested on your hardware with perf/token.js if you expect high volume. Scaling and performance