Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Routing based on JWT Claims #2452

Closed
arkodg opened this issue Jan 16, 2024 · 10 comments
Closed

Support Routing based on JWT Claims #2452

arkodg opened this issue Jan 16, 2024 · 10 comments
Assignees
Milestone

Comments

@arkodg
Copy link
Contributor

arkodg commented Jan 16, 2024

Description:

Describe the desired behavior, what scenario it enables and how it
would be used.

Users would like to route to a specific backend by matching on JWT claims

Looks like a popular issue raised in upstream as well kubernetes-sigs/gateway-api#920 but was closed due to lack of ownership

[optional Relevant Links:]

Any extra documentation required to understand the issue.

@arkodg
Copy link
Contributor Author

arkodg commented Jan 16, 2024

  • Some limitations we have from an Upstream API perspective - there is no first class field for claims within the matches field within HTTPRoute, this would be made it very easy for the user to author this intent
  • Envoy Gateway has a feature claimToHeaders https://gateway.envoyproxy.io/v0.6.0/api/extension_types/#claimtoheader
    to convert JWT claims to HTTP Headers which can be used for header matching, but from an implementation perspective JWT filter is applied at the route level, post route match. To support above use case, we could
    • automagically move the jwt filter to the hcm level if claimToHeaders is set
    • add a new field under jwt called useForRouting which also moves the jwt filter to the listener level

@arkodg arkodg added help wanted Extra attention is needed area/policy labels Jan 16, 2024
@arkodg arkodg self-assigned this Jan 17, 2024
@arkodg arkodg removed the help wanted Extra attention is needed label Jan 17, 2024
@arkodg
Copy link
Contributor Author

arkodg commented Jan 18, 2024

there's a clear_route_cache option in the JWT filter config https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/jwt_authn/v3/config.proto#extensions-filters-http-jwt-authn-v3-jwtprovider which clears the route decision and recomputes it, but based on the info

Clears route cache in order to allow JWT token to correctly affect routing decisions. Filter clears all cached routes when:

The field is set to true.
At least one claim_to_headers header is added to the request OR if payload_in_metadata is set.

it doesnt look like it needs to be set

@tmsnan
Copy link
Contributor

tmsnan commented Jan 18, 2024

@arkodg
Copy link
Contributor Author

arkodg commented Jan 18, 2024

nice find @tmsnan, does that logic need to be updated to

provider.clear_route_cache() || .......

?

@tmsnan
Copy link
Contributor

tmsnan commented Jan 19, 2024

No changes needed @arkodg. Recalculating routes may cause performance issues. In some scenarios, only header or metadata information needs to be added without requiring rerouting, such as ratelimit-based JWT claims.
Envoy comment needs to be updated.

arkodg added a commit to arkodg/gateway that referenced this issue Feb 14, 2024
Add a field called `useForRouting` that signals to Envoy Gateway
that the headers generated from the claims are used to make routing
decisions

Internally this field will be used to
* insert a catch-all route with a 404 direct response
identical to envoyproxy#2586 which
makes sure the jwt filter with `claimToHeader` is applied before
recomputing routing decision
* enable `clear_route_cache` to recompute routing decision
https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/jwt_authn/v3/config.proto#extensions-filters-http-jwt-authn-v3-jwtprovider

Relates to envoyproxy#2452

Signed-off-by: Arko Dasgupta <[email protected]>
Copy link

This issue has been automatically marked as stale because it has not had activity in the last 30 days.

@github-actions github-actions bot added the stale label Feb 18, 2024
@arkodg arkodg removed the stale label Feb 19, 2024
@arkodg arkodg added this to the v1.0.0-rc1 milestone Feb 19, 2024
arkodg added a commit to arkodg/gateway that referenced this issue Feb 20, 2024
Add a field called `useForRouting` that signals to Envoy Gateway
that the headers generated from the claims are used to make routing
decisions

Internally this field will be used to
* insert a catch-all route with a 404 direct response
identical to envoyproxy#2586 which
makes sure the jwt filter with `claimToHeader` is applied before
recomputing routing decision
* enable `clear_route_cache` to recompute routing decision
https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/jwt_authn/v3/config.proto#extensions-filters-http-jwt-authn-v3-jwtprovider

Relates to envoyproxy#2452

Signed-off-by: Arko Dasgupta <[email protected]>
arkodg added a commit to arkodg/gateway that referenced this issue Feb 23, 2024
Add a field called `useForRouting` that signals to Envoy Gateway
that the headers generated from the claims are used to make routing
decisions

Internally this field will be used to
* insert a catch-all route with a 404 direct response
identical to envoyproxy#2586 which
makes sure the jwt filter with `claimToHeader` is applied before
recomputing routing decision
* enable `clear_route_cache` to recompute routing decision
https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/jwt_authn/v3/config.proto#extensions-filters-http-jwt-authn-v3-jwtprovider

Relates to envoyproxy#2452

Signed-off-by: Arko Dasgupta <[email protected]>
arkodg added a commit that referenced this issue Feb 23, 2024
* api: useForRouting field in JWT

Add a field called `useForRouting` that signals to Envoy Gateway
that the headers generated from the claims are used to make routing
decisions

Internally this field will be used to
* enable `clear_route_cache` to recompute routing decision
https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/jwt_authn/v3/config.proto#extensions-filters-http-jwt-authn-v3-jwtprovider

Relates to #2452

Signed-off-by: Arko Dasgupta <[email protected]>

* helm

Signed-off-by: Arko Dasgupta <[email protected]>

* optional

Signed-off-by: Arko Dasgupta <[email protected]>

* rename to recomputeRoute

Signed-off-by: Arko Dasgupta <[email protected]>

* address comments

Signed-off-by: Arko Dasgupta <[email protected]>

---------

Signed-off-by: Arko Dasgupta <[email protected]>
arkodg added a commit to arkodg/gateway that referenced this issue Feb 24, 2024
arkodg added a commit that referenced this issue Feb 24, 2024
@zetaab
Copy link
Contributor

zetaab commented Feb 24, 2024

I added this to my jwt path and trying to figure out why it is not working:

% egctl config envoy-proxy listener -l gateway.envoyproxy.io/owning-gateway-name=internal > listener
error: proto: (line 2899:18): unknown field "clear_route_cache"

worth of adding new issue or?

@zirain
Copy link
Contributor

zirain commented Feb 25, 2024

I added this to my jwt path and trying to figure out why it is not working:

% egctl config envoy-proxy listener -l gateway.envoyproxy.io/owning-gateway-name=internal > listener
error: proto: (line 2899:18): unknown field "clear_route_cache"

worth of adding new issue or?

are you using the latest of egctl?

@zetaab
Copy link
Contributor

zetaab commented Feb 25, 2024

sorry, forgot to compile newest egctl. With newest egctl I can dump the configuration. However, the JWT based routing does not work with the PR which added clear_route_cache to JWT.

configuration:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: echoserver-int
  namespace: echoserver
spec:
  parentRefs:
  - name: internal
    namespace: envoy-gateway-system
    sectionName: https
  hostnames:
  - foobar.com
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: echoserver
      port: 80
      weight: 1
    matches:    
    - path:
        type: PathPrefix
        value: /
      headers:
      - name: x-sub
        type: Exact
        value: ca28333f-177f-4b7a-90c3-83951bc0eda4
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: echoserver-int-oidc
  namespace: echoserver
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: echoserver-int
  oidc:
    provider:
      issuer: https://cognito-idp.eu-central-1.amazonaws.com/xxx
    clientID: yy
    scopes:
    - openid
    - email
    - profile
    clientSecret:
      group: ""
      kind: Secret
      name: my-cognito-client-secret
  jwt:
    providers:
    - name: cognito
      recomputeRoute: true
      claimToHeaders:
      - claim: sub
        header: x-sub
      - claim: cognito:groups
        header: x-groups
      - claim: email
        header: x-email
      - claim: name
        header: x-name
      remoteJWKS:
        uri: https://cognito-idp.eu-central-1.amazonaws.com/xxx/.well-known/jwks.json

my application behind httproute is echoserver, if I remove that headers filter. I can see the x-sub and that same value in the response. Also if I remove securitypolicy and just use -H 'x-sub: ca28333f-177f-4b7a-90c3-83951bc0eda4' as curl parameters, the routing will work. So as I see it: new recomputeRoute parameter does not work like it was assumed. Is this tested and verified that it should work?

@arkodg
Copy link
Contributor Author

arkodg commented Feb 25, 2024

@zetaab plan on wrapping up a few higher priority work items for v1 rc before adding e2e and docs for this feature, should hopefully complete it by next week.
for your case you're missing a catchall route (e.g. a route rule for a / prefix match with a direct response of 404), that the route can match on first, convert the claim to header, and then recompute the route and match on your route rule with the x-sub match. We were initially planning on adding the catchall rule by default within EG, but based on community feedback, we're going to document and ask users to do it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests

4 participants