Skip to content

feat(openiddict): start on ephemeral keys with a warning when certs are missing#280

Merged
antosubash merged 2 commits into
mainfrom
worktree-openiddict-cert-fallback
Jul 22, 2026
Merged

feat(openiddict): start on ephemeral keys with a warning when certs are missing#280
antosubash merged 2 commits into
mainfrom
worktree-openiddict-cert-fallback

Conversation

@antosubash

@antosubash antosubash commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

A real deployment (plain docker run, or a PaaS like Dokploy where the image inherits Production) previously refused to start until OpenIddict signing/encryption certificates were configured:

System.InvalidOperationException: 'OpenIddict:SigningCertificatePath' and
'OpenIddict:EncryptionCertificatePath' must be configured in Production.

The app now starts on ephemeral keys and logs a prominent warning instead, so the image works out of the box on Dokploy/Coolify/plain Docker.

Guard behavior in real deployments (Development/Testing exempt):

Config state Behavior
ROPC password grant enabled throw (unchanged)
Both cert paths set silent — PKCS#12 certs loaded
Neither cert path set warning + ephemeral keys (new — was: throw)
Exactly one cert path set throw naming the missing key (new — a lone cert would be silently ignored, so partial config is always an operator mistake)

Trade-off (deliberate): ephemeral keys regenerate on every restart, invalidating all issued tokens and signing everyone out on each redeploy. The warning, README, and identity docs all state this; real certificates remain the documented requirement for anything beyond a throwaway deployment.

Changes

  • OpenIddictProductionGuard — warn-on-missing / throw-on-partial cert logic (LoggerMessage warning naming both config keys and the restart consequence); ROPC check unchanged
  • OpenIddictModule — updated two stale comments that claimed the guard still refuses ephemeral keys
  • README — documents the fallback, the both-or-neither rule, and openssl commands to generate the two PKCS#12 certs (+ OpenIddict__CertificatePassword)
  • docs/site/guide/identity.mdfixed wrong config key names (SigningCertPath/EncryptionCertPath/CertPasswordSigningCertificatePath/EncryptionCertificatePath/CertificatePassword) and documented the fallback
  • docker-compose.yml — updated the environment comment

Verification

Unit tests (TDD): 10 guard tests pin all four behavior branches both directions (confirmed red before each change) — 42/42 OpenIddict tests green.

Runtime, exact failure scenario from the bug report:

  • Local run, ASPNETCORE_ENVIRONMENT=Production, no certs → warning logged, Application started
  • Docker image built from this branch, plain docker run (no env) → warning logged, Application started, HTTP 200; gzip asset serving verified (text/css/text/javascript)

Code review (2 rounds): 3-lens review (conventions / logic / silent-failure) found 2 issues — both fixed in the second commit (stale comment; half-configured pair originally degraded silently → now throws naming the missing key). Re-review by 2 fresh reviewers: no findings.

Browser QA (full /qa cycle, 1 iteration, ALL CLEAN): 30/30 tests across happy-path (9), form-validation (13), error-states (8) on the ephemeral-key token path — login/logout both roles, registration + auto-login, OIDC endpoints return proper OAuth 400s (no 500s), no account enumeration on login, two-tab session propagation, friendly 404s, zero console errors.

Local CI mirror: biome ✓ · validate-pages ✓ · validate:i18n ✓ · framework-scope ✓ · typecheck 15/15 ✓ · dotnet build 0 warnings ✓ · dotnet test 20/20 assemblies (exit 0) ✓ · e2e smoke 66/66 ✓ · npm run build

Test plan

  • Reviewer runs the image with no env vars and sees the ephemeral-keys warning + successful startup
  • Reviewer sets exactly one cert path and confirms startup fails naming the missing key
  • CI is green

…re missing

A real deployment (a plain `docker run`, or a PaaS like Dokploy where the
image inherits Production) previously refused to start until OpenIddict
signing/encryption certificates were configured. The app now starts on
ephemeral keys and logs a prominent warning instead: those keys regenerate on
every restart, invalidating all issued tokens and signing everyone out on each
redeploy, so certificates remain the documented requirement for anything
beyond a throwaway deployment. The ROPC password-grant guard still fails
startup.

Also fixes docs/site/guide/identity.md, which documented wrong config key
names (SigningCertPath/EncryptionCertPath/CertPassword instead of
SigningCertificatePath/EncryptionCertificatePath/CertificatePassword), and
adds openssl cert-generation instructions to the README.
Half-configured certificate pair (exactly one path set) now fails startup naming the missing key — the module ignores a lone certificate, so partial config is always an operator mistake. Warning-fallback remains for the fully-unconfigured case. Also fixes a stale guard-registration comment.
@antosubash
antosubash marked this pull request as ready for review July 22, 2026 14:38
@antosubash
antosubash merged commit 1fa2192 into main Jul 22, 2026
10 checks passed
@antosubash
antosubash deleted the worktree-openiddict-cert-fallback branch July 22, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant