feat(openiddict): start on ephemeral keys with a warning when certs are missing#280
Merged
Merged
Conversation
…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
marked this pull request as ready for review
July 22, 2026 14:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A real deployment (plain
docker run, or a PaaS like Dokploy where the image inheritsProduction) previously refused to start until OpenIddict signing/encryption certificates were configured: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):
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 unchangedOpenIddictModule— updated two stale comments that claimed the guard still refuses ephemeral keysOpenIddict__CertificatePassword)docs/site/guide/identity.md— fixed wrong config key names (SigningCertPath/EncryptionCertPath/CertPassword→SigningCertificatePath/EncryptionCertificatePath/CertificatePassword) and documented the fallbackdocker-compose.yml— updated the environment commentVerification
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:
ASPNETCORE_ENVIRONMENT=Production, no certs → warning logged,Application starteddocker 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 build0 warnings ✓ ·dotnet test20/20 assemblies (exit 0) ✓ · e2e smoke 66/66 ✓ ·npm run build✓Test plan