-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
envoy: use upstream JWT filter instead of the custom Istio extension #47407
Conversation
Change-Id: I1a34a470f9770e1c7990e12a8370ee93fb297279 Signed-off-by: Kuat Yessenov <kuat@google.com>
Change-Id: I99c29a3b28ffad9ae4125b2ea9da1d00b0430044 Signed-off-by: Kuat Yessenov <kuat@google.com>
Change-Id: I87ef250fe59af07aa43ae0684fe944dc446f5713 Signed-off-by: Kuat Yessenov <kuat@google.com>
Change-Id: Id46d841ab58abfcb619d4c15df23604e2aafd26e
Change-Id: Ie69f3d0728e9b4c48c9d6807e67075a904066d66
Change-Id: I0e684914d85f6fb5edebd92127e0426f5b05b4c3 Signed-off-by: Kuat Yessenov <kuat@google.com>
Change-Id: Ia1bba5731a98d8841adbe99ae1d1518cbafa852a Signed-off-by: Kuat Yessenov <kuat@google.com>
pilot/pkg/networking/core/v1alpha3/route/route_internal_test.go
Outdated
Show resolved
Hide resolved
@@ -270,7 +270,7 @@ func buildRBAC(node *model.Proxy, push *model.PushContext, suffix string, contex | |||
for _, policy := range policies { | |||
for i, rule := range policy.Spec.Rules { | |||
name := fmt.Sprintf("%s-%s-%d", policy.Namespace, policy.Name, i) | |||
m, err := authzmodel.New(rule) | |||
m, err := authzmodel.New(rule, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does grpc support this filter before? I am concerned about the compatibility here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gRPC doesn't support it either way. Any value here would not work for JWT.
@@ -32,7 +32,7 @@ type PolicyApplier interface { | |||
|
|||
// JwtFilter returns the JWT HTTP filter to enforce the underlying authentication policy. | |||
// It may return nil, if no JWT validation is needed. | |||
JwtFilter() *hcm.HttpFilter | |||
JwtFilter(useExtendedJwt, clearRouteCache bool) *hcm.HttpFilter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clearRouteCache looks weired
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestions? That's what xDS field is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually i am not familiar with jwt clear cache, will take a look though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is to clear the cache used for making route decision, right? @kyessenov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's to re-calculate the route selection
@@ -99,8 +99,15 @@ func (b *Builder) BuildHTTP(class networking.ListenerClass) []*hcm.HttpFilter { | |||
// Only applies to inbound and gateways | |||
return nil | |||
} | |||
if b.proxy.SupportsEnvoyExtendedJwt() { | |||
filter := b.applier.JwtFilter(true, b.proxy.Type != model.SidecarProxy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we clear cache only for no sidecar? can we always set it true
And actually envoy only clear when ClearRouteCache = true and claim_to_headers
added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It only makes sense on gateways because there are routes there. Inbound listener has no routes, see https://istio.io/latest/docs/tasks/security/authentication/jwt-route/ disclaimer at the top.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IC,i mean once we add another type, this could be broken. Is there any side-effect if we set it true for sidecar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it causes overhead to reset a cache. It is also backwards incompatible since other filters might affect the route as well.
Change-Id: I67743d13a0670fca111cfe8dd923bc3f6906625a
Gentle ping. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall lgtm
if forTCP { | ||
return nil, fmt.Errorf("%q is HTTP only", key) | ||
} | ||
|
||
if rpg.useExtendedJwt { | ||
iss, sub, _ := strings.Cut(value, "/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably reject if there is no /
in it here, and add a warning into the webhook if a user does this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it was valid to have something like a*
which matches iss with prefix a
and any sub
. Let me update it.
} | ||
im := MetadataMatcherForJWTClaims([]string{"iss"}, matcher.StringMatcher(iss), true) | ||
sm := MetadataMatcherForJWTClaims([]string{"sub"}, matcher.StringMatcher(sub), true) | ||
return principalAnd([]*rbacpb.Principal{principalMetadata(im), principalMetadata(sm)}), nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we would now allow matching a*/b
where before we would not since we treated the whole thing as one unit.
Which is probably reasonable. Not sure why we didn't just make 2 fields to begin with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeap, added a fix for this.
Any more comments? |
@@ -1338,6 +1338,13 @@ func (node *Proxy) WorkloadEntry() (string, bool) { | |||
return node.workloadEntryName, node.workloadEntryAutoCreated | |||
} | |||
|
|||
// SupportsEnvoyExtendedJwt indicates that the proxy JWT extension is capable of | |||
// replacing istio_authn filter. | |||
func (node *Proxy) SupportsEnvoyExtendedJwt() bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wouldn't be a breaking change for any user right and users don't need to configure this? Why can't we just cherrypick for all the supported versions instead of maintaining different configs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should be fully compatible - it's never 100% but close to it. We can't backport Envoy features, that's against the project policy to backport features and not fixes.
@@ -226,6 +226,13 @@ func convertToEnvoyJwtConfig(jwtRules []*v1beta1.JWTRule, push *model.PushContex | |||
ForwardPayloadHeader: jwtRule.OutputPayloadToHeader, | |||
PayloadInMetadata: jwtRule.Issuer, | |||
} | |||
if useExtendedJwt { | |||
provider.PayloadInMetadata = filters.EnvoyJwtFilterPayload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would break a user who is already assuming Issuer in the payload and using that for some reason? We should atlease document this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean the internal dynamic metadata from istio_authn? That was not a contract we generally follow - most of Envoy internal interfaces are private for a good reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean any user can have a custom envoy filter that is reading the dynamic metadata from jwt_authn filter. It could break them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
previously we were just adding issuer now payload
. Wouldn't it be a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if they have a custom Envoy/Wasm filter, they need to update. That's always the expectation that the low-level Envoy interfaces are not stable; otherwise, we could never make Envoy changes. I'll update the change note to warn against this. It's a fairly simple change to rename the metadata key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good!!
res := []*hcm.HttpFilter{} | ||
if filter := b.applier.JwtFilter(); filter != nil { | ||
if filter := b.applier.JwtFilter(false, false); filter != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where's the code to ignore the istio_authn filter. I see we are still building isito_authn filter for all the cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above if
block exits early.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah I missed that. Thanks
Change-Id: I668691cc926be197a253827ff02e85bf2bebd6fc
Change-Id: Iaea2503e3f0403766b96442ae3b3ce490e8bac08 Signed-off-by: Kuat Yessenov <kuat@google.com>
res := []*hcm.HttpFilter{} | ||
if filter := b.applier.JwtFilter(); filter != nil { | ||
if filter := b.applier.JwtFilter(false, false); filter != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah I missed that. Thanks
@@ -226,6 +226,13 @@ func convertToEnvoyJwtConfig(jwtRules []*v1beta1.JWTRule, push *model.PushContex | |||
ForwardPayloadHeader: jwtRule.OutputPayloadToHeader, | |||
PayloadInMetadata: jwtRule.Issuer, | |||
} | |||
if useExtendedJwt { | |||
provider.PayloadInMetadata = filters.EnvoyJwtFilterPayload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good!!
@ericvn can I get a test&release WG review? |
@ericvn is OoO, @howardjohn can you give this another look, please? |
This PR looks to have caused a failure in step 3 of the jwt-route test: https://istio.io/latest/docs/tasks/security/authentication/jwt-route/#validating-ingress-routing-based-on-jwt-claims. Docs say we should get a 200, but we are getting back a 404. |
Change-Id: I1a34a470f9770e1c7990e12a8370ee93fb297279
Modifies xDS to use the upstream JWT filter from Envoy instead of the extra Istio
istio_authn
HTTP filter for JWT matching and JWT policy evaluation. It is functionally equivalent with the main difference being that the space-delimited claims must be explicitly opted-in. The default space-delimited claims arescope
andpermission
.Issue: envoyproxy/envoy#29681