feat: add jwtDirect filter for JWT validation with direct JWKS URL#3922
feat: add jwtDirect filter for JWT validation with direct JWKS URL#3922ivan-digital wants to merge 3 commits intozalando:masterfrom
Conversation
Add a new jwtDirect filter that verifies JWT Bearer tokens using a JWKS URL directly, without requiring OIDC discovery. Supports arbitrary claim key-value validation (e.g. iss, aud). This enables use cases like Google Chat webhook signature verification where the JWKS endpoint is not behind a standard .well-known/openid-configuration. Closes zalando#3921 Signed-off-by: ivan-digital <root@ivan.digital>
688f555 to
9eb5971
Compare
filters/auth/jwt_direct.go
Outdated
| }, nil | ||
| } | ||
|
|
||
| func (f *jwtDirectFilter) Request(ctx filters.FilterContext) { |
There was a problem hiding this comment.
Hi. Existing jwtValidation filter only validates token and delegates claims check to oidcClaimsQuery.
I think it makes sense to do the same here, moreover Request logic seems to be exactly the same and therefore could be reused - you can simply return an instance of jwtValidationFilter from the spec.
As for the name I'd suggest jwtValidationKeys as "direct" is a bit obscure.
Please also add docs to filters.md nearby jwtValidation. Thanks!
(PS: I am not actively involved in Skipper development anymore but I recently saw your great work on ASR/TTS so decided to chime in 👋)
There was a problem hiding this comment.
Thanks for the review and the valuable simplifications! Addressed all points: renamed to jwtValidationKeys, reusing jwtValidationFilter from the spec, moved registration next to jwtValidation in skipper.go, and added docs to filters.md. Claims validation delegated to oidcClaimsQuery as suggested. Thanks for the attention :)
There was a problem hiding this comment.
@AlexanderYastrebov it's always a great contribution if you review code, much appreciated :)
filters/builtin/builtin.go
Outdated
| accesslog.NewEnableAccessLog(), | ||
| auth.NewForwardToken(), | ||
| auth.NewForwardTokenField(), | ||
| auth.NewJwtDirect(), |
There was a problem hiding this comment.
Register it nearby existing jwtValidation filter instead of builtin.
There was a problem hiding this comment.
Done, moved to skipper.go next to jwtValidation.
Add a new jwtValidationKeys filter that verifies JWT Bearer tokens using a JWKS URL directly, without requiring OIDC discovery. Reuses jwtValidationFilter for token parsing and validation logic. Claims checking is delegated to oidcClaimsQuery as per existing convention. Renamed from jwtDirect to jwtValidationKeys for clarity. Registered alongside jwtValidation in skipper.go instead of builtin. Added docs to filters.md. Closes zalando#3921 Signed-off-by: ivan-digital <root@ivan.digital>
Use correct @_ modifier and == operator for exact claim matching. Chain separate oidcClaimsQuery filters for AND logic since queries within a single argument are OR-matched. Signed-off-by: ivan-digital <root@ivan.digital>
|
code looks fine I would move it to the same file as the implementation that you borrow from or rename to filter name |
Summary
jwtDirectfilter that verifies JWT Bearer tokens using a JWKS URL directly, without requiring OIDC discovery via.well-known/openid-configurationkeyfunclibrary and JWKS caching infrastructureMotivation
The existing
jwtValidationfilter only supports JWKS discovery via OIDC.well-known/openid-configuration. Services like Google Chat bots publish JWKS keys at non-standard URLs and requireiss/audclaim validation, which is currently not possible.Usage
Closes #3921
Test plan