Skip to content

Go-live checklist ​

Each item states what must be true before production and links to the page that explains it. examples/53-production-sql wires most of them in one program.

Keys ​

  • Signing keys and cookie keys are loaded from persistent storage with op.LoadKeyset and op.LoadSymmetricKeys, so every replica publishes the same kid and a restart does not log users out. See Key rotation.
  • A rotation plan exists: the retiring signing key and the retiring cookie key stay listed until the tokens and sessions they protected have expired. See Key rotation.

Storage ​

  • The schema is applied once per release from a deploy job, either by your migration tool from Store.Migrations() or by Store.Migrate(ctx), not from every replica's startup. See Storage maintenance.
  • On MySQL, the indexes and the binary collations of an existing database come from the files in Store.Migrations(), which Store.Migrate or your tool applies. The schema check reports a missing index and a non-binary collation. See Persistent storage (SQL).
  • op.New checks at startup the schema of the tables the configuration uses, so a missing table or column stops the start-up instead of failing a later request; Store.ValidateSchema validates all tables in a deploy gate. See Persistent storage (SQL).
  • A retention sweep (Store.GC or RunGC) is scheduled on one replica. One is enough, and sweeps that overlap on several replicas are safe, so no leader election is needed. Nothing else deletes expired rows, so the tables grow without bound until it runs. See Storage maintenance.
  • Backups and recovery targets are set for each substore. See Backup & disaster recovery.

Network and clients ​

  • op.WithTrustedProxies lists the CIDRs of the reverse proxy or ingress, so the OP sees the real client address and scheme. Without it the X-Forwarded-* headers are ignored. See Mount on your router.
  • Static clients are synchronised with op.SyncStaticClients from a deploy job before the new version starts. A changed definition is refused at startup until then. See Client onboarding.
  • The security profile is chosen on purpose, and the startup.profile audit event shows the posture you deployed. Without op.WithProfile PKCE is required of every client; a relying party that cannot send it is admitted only by declaring profile.OIDCCore. See Declaring a security profile.
  • Every static confidential client has a plaintext Secret of at least 32 bytes (mint one with op.NewClientSecret) or a SecretHash; op.New refuses a shorter Secret. See Client onboarding.
  • Clients that send DPoP proofs sign the endpoint URL the OP advertises in discovery, not an internal address behind the proxy; any other URL is refused whatever the profile.

Running it ​

  • No op.WithAllowInsecureOutboundForDev or op.WithAllowLocalhostIssuerForDev is in the production option list; both exist for a development issuer, and op.New refuses the former against any other.
  • op.WithLogger is set. Without it, construction warnings and the line that names optional store capabilities a custom store lacks go to slog.Default(), and every request-time record is discarded. See Observability.
  • The container memory limit allows GOMAXPROCS × 64 MiB for hashing. Each password check and each client_secret check runs Argon2id at 64 MiB and about 90 ms, and checks run concurrently up to GOMAXPROCS. A high-rate machine-to-machine client avoids the cost with op.WithHighEntropyClientSecrets. See Service-to-service (client_credentials).
  • Replicas share the session, grant and replay-set stores. With DPoP server nonces enabled they also share one op.DPoPNonceSource, and a login flow with a password or second-factor step has a durable, shared lockout store. See Multi-instance deployment.
  • Shutdown stops the HTTP server first and then calls Provider.Shutdown, so queued back-channel logout deliveries finish. See Multi-instance deployment.
  • If the handler is built with op.NewReloadable, a key or option change is applied with Reload, and the same option list is used at startup and on every reload. See Key rotation.