Title: Add a HTTP filter for JWT verification
Description:
JWT verification is important for many services. This filter will allow Envoy proxy to verify the JWT token by fetching the remote pubkey and pass the verified JWT payload to the services for further authorization.
Istio has this filter here: https://github.com/istio/proxy/tree/master/src/envoy/http/jwt_auth
This issue wants to upstream the filter to Envoy.
SGTM
I'll work with @qiwzhang to gradually move codes from istio/proxy. @mattklein123 can you assign the issue to me?
That's great to have this feature. Look istio implementation moved to https://github.com/istio/proxy/tree/master/src/envoy/http/jwt_auth
Really happy to see this moving forward (should be much more feature-complete than my custom filter). A couple questions though while we're still early in the process:
Also, is there anything blocked with migrating the istio/proxy code into envoy? Happy to help if I can plug in somewhat easily.
The current config doesn't support route-specific filter yet, but it could/would happen in near future.
I don't think we want to do more fine granularity than route with JWT authN filter, but with the upcoming RBAC filter you should be able to fine control the allow by default, etc.
Fair enough, agreed that the multi-audience stuff is getting more into authz than authn so maybe that should be deferred to the RBAC filter (first I'm hearing about it).
That said, I think we could tweak the current configs to use a list of route rules rather than a list of bypass. Should be more general than the current bypass scheme without the complexity of per-issuer or per-audience rules.
name: "jwt-auth"
config:
rules: [...]
routes:
- match: { prefix: "/api/" }
action: require
- match: { prefix: "/example/" }
action: optional # parse and verify, forward if valid
- match: { prefix: "/" }
action: bypass
I happened to be looking at some google api docs and noticed that their api has support for per-route issuer/audience verification: https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.Authentication
After thinking about it a bit more, it does seem appropriate to include route-specific issuer/audience checks as part of the authn filter. We're not filtering based on who the _user_ is or what scopes/claims they have (in which case I agree it would be getting too far into authz). We're filtering based on whether the _token_ is valid for the resource it's trying to access.
The configuration wouldn't need to change that much to support this. As a hypothetical, it could look something like this:
name: "jwt-authn"
config:
providers:
- id: bookstore_auth
issuer: https://securetoken.google.com
audiences:
- bookstore_android.apps.googleusercontent.com
- bookstore_web.apps.googleusercontent.com
remote_jwks: [...] # same as existing, omitted for brevity
rules:
- match: { prefix: "/bookstore/" }
requirements: [{ provider_id: bookstore_auth }]
- match: { prefix: "/" }
requirements: []
Content-wise, it's about the same as the existing proposal, it just gives providers ids so they can be referenced in the rules/requirements.
My plan is to support per_route config in route::per_filter_config. You can put the whole JwtAuthentiction config into this per_filter_config. It may not be optimal since you have to specify jwt rules for each route, but it will serve most use cases.
@llchan will that work for you?
That would in theory work, but the config would be very verbose compared to the proposal above. One implicit advantage of the above is that the level of JWT granularity is decoupled from the routing, and the user can choose how to organize the JWT authn. I can, for example, have 100 route entries, but only 2 jwt-authn rules filtering audiences for prefixes of "/api/v1/" and "/api/v2/". That's just an example, but the main idea is that the granularity is configurable.
I suppose this is not a dealbreaker and per-route configs would work, because I could potentially just use a config generator to expand a more compact config, but I'm curious if there are concrete design flaws/deficiencies with the above?
Hi @llchan, One concern of your proposal is: you put route specific requirement rules in the filter config, it will be send to Envoy as LDS. But route could change dynamically, per-route specific info is preferred to send to Envoy in RDS. We don't want a route change to cause LDS update which is expensive.
Based on your idea, I will propose to move route specific requirement rules into per_route config. but keep providers list in the filter config.
Ah thanks, I understand now. I'm currently using static configs so I didnt think about dynamic updates. I think the hybrid approach of defining providers in the filter config and referencing them in per-route filter configs is a nice middle-ground.
This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.
Status update:
This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.
Is there some documentation about how to use this? Thanks!
Official document is not added yet. But you can look at the config proto file here https://github.com/envoyproxy/envoy/blob/master/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto
This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.
Bump for stale bot. Still interested in this!
We already have sort of support for JWT verification, can we mark this done after #4101? What else on your list? @qiwzhang
We can mark it as done after #4101
Done.
Most helpful comment
Is there some documentation about how to use this? Thanks!