feat(auth): allow missing exp per JWKS while rejecting expired tokens#8911
feat(auth): allow missing exp per JWKS while rejecting expired tokens#8911fernando-apollo wants to merge 2 commits intodevfrom
exp per JWKS while rejecting expired tokens#8911Conversation
✅ Docs preview readyThe preview is ready to be viewed. View the preview File Changes 0 new, 2 changed, 1 removedBuild ID: 65f0ce02cc91d18519dbc947 URL: https://www.apollographql.com/docs/deploy-preview/65f0ce02cc91d18519dbc947
|
950d2fd to
168e84c
Compare
168e84c to
7f1d73f
Compare
Summary
Adds a per-JWKS
allow_missing_expconfiguration option to the JWT authentication plugin. When enabled, tokens without anexp(expiry) claim are accepted for the configured JWKS endpoint. Tokens that do include anexpclaim are still validated and rejected if expired.This is useful for identity providers that issue tokens without expiry, such as long-lived service tokens or certain machine-to-machine flows.
Tracking issue: #8910
Motivation (customer context)
A prospect reported that some of their JWTs are intentionally long-lived and do not include an
expclaim (for example, service-to-service tokens). Router currently rejects those tokens because JWT validation requiresexp.They currently work around this with a sidecar and asked for a per-JWKS way to effectively “skip expiry validation”.
This PR implements a safer, narrower version of that request:
allow_missing_expis configured per JWKSexpcan be accepted (for that JWKS only)expare still validated and rejected if expiredKey behaviors
allow_missing_expis configured per JWKS entry, not globally. A token withoutexpis only accepted if it matches a JWKS that has the option enabled.exp. Ifexpis present and in the past, the token is rejected as usual.allow_missing_expis enabled, and an additional warning if neitherissuersnoraudiencesare configured alongside it.debuglog is emitted when a JWT withoutexpis accepted.SearchResultrefactor: Changed from a tuple to a named struct to cleanly thread the new field through JWKS search and JWT decoding.Configuration
Known limitation
Subscriptions currently use JWT expiry to determine a timeout. Tokens without
expare not timed out by JWT expiry. This behavior is intentionally not changed in this PR.Test plan
expby defaultexpwhenallow_missing_exp: trueallow_missing_exp: trueexpwhenallow_missing_exp: trueallow_missing_exp: trueallow_missing_exp: trueexpaccepted by JWKS A (allow_missing_exp: true) but rejected by JWKS B (allow_missing_exp: false)Verification run
cargo fmt --all --checkcargo test -p apollo-router plugins::authentication::tests::expiry_validation --no-fail-fast --lockedcargo test -p apollo-router plugins::authentication::jwks::test --no-fail-fast --lockedChecklist
Complete the checklist (and note appropriate exceptions) before the PR is marked ready-for-review.
Exceptions
exp, expiredexp, issuer/audience enforcement, and per-JWKS scoping).expJWTs is intentionally deferred to a follow-up PR.Notes
Footnotes
It may be appropriate to bring upcoming changes to the attention of other (impacted) groups. Please endeavour to do this before seeking PR approval. The mechanism for doing this will vary considerably, so use your judgement as to how and when to do this. ↩
Configuration is an important part of many changes. Where applicable please try to document configuration examples. ↩
A lot of (if not most) features benefit from built-in observability and
debug-level logs. Please read this guidance on metrics best-practices. ↩Tick whichever testing boxes are applicable. If you are adding Manual Tests, please document the manual testing (extensively) in the Exceptions. ↩