Skip to content

Commit

Permalink
envoy: use upstream JWT filter instead of the custom Istio extension (i…
Browse files Browse the repository at this point in the history
…stio#47407)

* test: remove istio_authn HTTP filter

Change-Id: I1a34a470f9770e1c7990e12a8370ee93fb297279
Signed-off-by: Kuat Yessenov <kuat@google.com>

* match principal

Change-Id: I99c29a3b28ffad9ae4125b2ea9da1d00b0430044
Signed-off-by: Kuat Yessenov <kuat@google.com>

* Revert "test: remove istio_authn HTTP filter"

This reverts commit b444bd2.

* Reapply "test: remove istio_authn HTTP filter"

This reverts commit ea73ad6.

* test

Change-Id: I2943e8a1fe415c7fa3558a903d374413a7e3a6da
Signed-off-by: Kuat Yessenov <kuat@google.com>

* map claims to envoy jwt

Change-Id: I87ef250fe59af07aa43ae0684fe944dc446f5713
Signed-off-by: Kuat Yessenov <kuat@google.com>

* value or

Change-Id: I243387881193c0676796472c30d0bcf07ca8c047
Signed-off-by: Kuat Yessenov <kuat@google.com>

* use scope delimited

Change-Id: I0e684914d85f6fb5edebd92127e0426f5b05b4c3
Signed-off-by: Kuat Yessenov <kuat@google.com>

* test

Change-Id: Ic5dabdc5cd6681899e251eaa89f1c221a9a285a7
Signed-off-by: Kuat Yessenov <kuat@google.com>

* drop authn

Change-Id: Ia1bba5731a98d8841adbe99ae1d1518cbafa852a
Signed-off-by: Kuat Yessenov <kuat@google.com>

* match any

Change-Id: I0695b5c1aefec0198886d0068cc3667c8c3225e1
Signed-off-by: Kuat Yessenov <kuat@google.com>

* presence

Change-Id: I31b1278dbeba17203766cade3f94c3003d366a9f
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: Ic1445984457022cf6099a3df43ad79c9f95b1e4d
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: Iaac6c9912d4d20851e524075f899e90827bea118
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: I9004b9bb5444feb371585bdf48083149f1b889bd
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: Ib548be09c75176e0bae32a77284dc7bf5aae67d7
Signed-off-by: Kuat Yessenov <kuat@google.com>

* revieww

Change-Id: I31a7035c45b2647379e365b72f4d5ef4cf3db6c3
Signed-off-by: Kuat Yessenov <kuat@google.com>

* fix

Change-Id: Iaf2d407dd1e95312d1aee5bf72a7da22f2b1c211
Signed-off-by: Kuat Yessenov <kuat@google.com>

* add tests

Change-Id: I8f0a68fa400f83e120a99ad634cac54cb5901758
Signed-off-by: Kuat Yessenov <kuat@google.com>

* add warning

Change-Id: Iaea2503e3f0403766b96442ae3b3ce490e8bac08
Signed-off-by: Kuat Yessenov <kuat@google.com>

---------

Signed-off-by: Kuat Yessenov <kuat@google.com>
  • Loading branch information
kyessenov authored Nov 20, 2023
1 parent 7033e70 commit d4d1475
Show file tree
Hide file tree
Showing 22 changed files with 455 additions and 60 deletions.
7 changes: 7 additions & 0 deletions pilot/pkg/model/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
return node.IstioVersion == nil ||
node.IstioVersion.Compare(&IstioVersion{Major: 1, Minor: 21, Patch: -1}) >= 0
}

type GatewayController interface {
ConfigStoreController
// Reconcile updates the internal state of the gateway controller for a given input. This should be
Expand Down
2 changes: 1 addition & 1 deletion pilot/pkg/networking/core/v1alpha3/listener_waypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ func (lb *ListenerBuilder) translateRoute(

out := &route.Route{
Name: routeName,
Match: istio_route.TranslateRouteMatch(virtualService, match),
Match: istio_route.TranslateRouteMatch(virtualService, match, true),
Metadata: util.BuildConfigInfoMetadata(virtualService.Meta),
}
authority := ""
Expand Down
14 changes: 7 additions & 7 deletions pilot/pkg/networking/core/v1alpha3/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ func translateRoute(

out := &route.Route{
Name: routeName,
Match: TranslateRouteMatch(virtualService, match),
Match: TranslateRouteMatch(virtualService, match, node.SupportsEnvoyExtendedJwt()),
Metadata: util.BuildConfigInfoMetadata(virtualService.Meta),
}

Expand Down Expand Up @@ -956,15 +956,15 @@ func TranslateHeadersOperations(headers *networking.Headers) HeadersOperations {
}

// TranslateRouteMatch translates match condition
func TranslateRouteMatch(vs config.Config, in *networking.HTTPMatchRequest) *route.RouteMatch {
func TranslateRouteMatch(vs config.Config, in *networking.HTTPMatchRequest, useExtendedJwt bool) *route.RouteMatch {
out := &route.RouteMatch{PathSpecifier: &route.RouteMatch_Prefix{Prefix: "/"}}
if in == nil {
return out
}

for name, stringMatch := range in.Headers {
// The metadata matcher takes precedence over the header matcher.
if metadataMatcher := translateMetadataMatch(name, stringMatch); metadataMatcher != nil {
if metadataMatcher := translateMetadataMatch(name, stringMatch, useExtendedJwt); metadataMatcher != nil {
out.DynamicMetadata = append(out.DynamicMetadata, metadataMatcher)
} else {
matcher := translateHeaderMatch(name, stringMatch)
Expand All @@ -973,7 +973,7 @@ func TranslateRouteMatch(vs config.Config, in *networking.HTTPMatchRequest) *rou
}

for name, stringMatch := range in.WithoutHeaders {
if metadataMatcher := translateMetadataMatch(name, stringMatch); metadataMatcher != nil {
if metadataMatcher := translateMetadataMatch(name, stringMatch, useExtendedJwt); metadataMatcher != nil {
metadataMatcher.Invert = true
out.DynamicMetadata = append(out.DynamicMetadata, metadataMatcher)
} else {
Expand Down Expand Up @@ -1085,12 +1085,12 @@ func isCatchAllStringMatch(in *networking.StringMatch) bool {
// Examples using `[]` as a separator:
// - `@request.auth.claims[admin]` matches the claim "admin".
// - `@request.auth.claims[group][id]` matches the nested claims "group" and "id".
func translateMetadataMatch(name string, in *networking.StringMatch) *matcher.MetadataMatcher {
func translateMetadataMatch(name string, in *networking.StringMatch, useExtendedJwt bool) *matcher.MetadataMatcher {
rc := jwt.ToRoutingClaim(name)
if !rc.Match {
return nil
}
return authz.MetadataMatcherForJWTClaims(rc.Claims, util.ConvertToEnvoyMatch(in))
return authz.MetadataMatcherForJWTClaims(rc.Claims, util.ConvertToEnvoyMatch(in), useExtendedJwt)
}

// translateHeaderMatch translates to HeaderMatcher
Expand Down Expand Up @@ -1191,7 +1191,7 @@ func buildDefaultHTTPRoute(clusterName string, operation string) *route.Route {
ClusterSpecifier: &route.RouteAction_Cluster{Cluster: clusterName},
}
val := &route.Route{
Match: TranslateRouteMatch(config.Config{}, nil),
Match: TranslateRouteMatch(config.Config{}, nil, true),
Decorator: &route.Decorator{
Operation: operation,
},
Expand Down
31 changes: 20 additions & 11 deletions pilot/pkg/networking/core/v1alpha3/route/route_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,8 @@ func TestTranslateMetadataMatch(t *testing.T) {
name string
in *networking.StringMatch
want *matcher.MetadataMatcher

useExtended bool
}{
{
name: "@request.auth.claims",
Expand All @@ -572,27 +574,27 @@ func TestTranslateMetadataMatch(t *testing.T) {
{
name: "@request.auth.claims.key1",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"key1"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"key1"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims.key1.KEY2",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"key1", "KEY2"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"key1", "KEY2"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims.key1-key2",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"key1-key2"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"key1-key2"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims.prefix",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Prefix{Prefix: "prefix"}},
want: authz.MetadataMatcherForJWTClaims([]string{"prefix"}, authzmatcher.StringMatcher("prefix*")),
want: authz.MetadataMatcherForJWTClaims([]string{"prefix"}, authzmatcher.StringMatcher("prefix*"), false),
},
{
name: "@request.auth.claims.regex",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Regex{Regex: ".+?\\..+?\\..+?"}},
want: authz.MetadataMatcherForJWTClaims([]string{"regex"}, authzmatcher.StringMatcherRegex(".+?\\..+?\\..+?")),
want: authz.MetadataMatcherForJWTClaims([]string{"regex"}, authzmatcher.StringMatcherRegex(".+?\\..+?\\..+?"), false),
},
{
name: "@request.auth.claims[key1",
Expand All @@ -611,32 +613,39 @@ func TestTranslateMetadataMatch(t *testing.T) {
// if `.` exists, use `.` as separator
name: "@request.auth.claims.[key1]",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"[key1]"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"[key1]"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims[key1]",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"key1"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"key1"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims[key1][key2]",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"key1", "key2"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"key1", "key2"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims[test-issuer-2@istio.io]",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"test-issuer-2@istio.io"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"test-issuer-2@istio.io"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims[test-issuer-2@istio.io][key1]",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"test-issuer-2@istio.io", "key1"}, authzmatcher.StringMatcher("exact"), false),
},
{
name: "@request.auth.claims[test-issuer-2@istio.io][key1]",
in: &networking.StringMatch{MatchType: &networking.StringMatch_Exact{Exact: "exact"}},
want: authz.MetadataMatcherForJWTClaims([]string{"test-issuer-2@istio.io", "key1"}, authzmatcher.StringMatcher("exact")),
want: authz.MetadataMatcherForJWTClaims([]string{"test-issuer-2@istio.io", "key1"}, authzmatcher.StringMatcher("exact"), true),

useExtended: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := translateMetadataMatch(tc.name, tc.in)
got := translateMetadataMatch(tc.name, tc.in, tc.useExtended)
if !reflect.DeepEqual(got, tc.want) {
t.Errorf("Unexpected metadata matcher want %v, got %v", tc.want, got)
}
Expand Down
27 changes: 27 additions & 0 deletions pilot/pkg/networking/core/v1alpha3/route/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"istio.io/istio/pilot/pkg/networking/core/v1alpha3"
"istio.io/istio/pilot/pkg/networking/core/v1alpha3/route"
"istio.io/istio/pilot/pkg/networking/util"
"istio.io/istio/pilot/pkg/xds/filters"
"istio.io/istio/pilot/test/xdstest"
"istio.io/istio/pkg/config"
"istio.io/istio/pkg/config/constants"
Expand Down Expand Up @@ -59,9 +60,19 @@ func TestBuildHTTPRoutes(t *testing.T) {
IPAddresses: []string{"1.1.1.1"},
ID: "someID",
DNSDomain: "foo.com",
IstioVersion: &model.IstioVersion{
Major: 1,
Minor: 20,
},
})
}

nodeWithExtended := func(cg *v1alpha3.ConfigGenTest) *model.Proxy {
out := node(cg)
out.IstioVersion.Minor = 21
return out
}

gatewayNames := sets.New("some-gateway")

t.Run("for virtual service", func(t *testing.T) {
Expand Down Expand Up @@ -275,6 +286,22 @@ func TestBuildHTTPRoutes(t *testing.T) {
g.Expect(routes[0].GetMatch().GetDynamicMetadata()[1].GetInvert()).To(BeTrue())
})

t.Run("for virtual service with exact matching on JWT claims with extended", func(t *testing.T) {
g := NewWithT(t)
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})

routes, err := route.BuildHTTPRoutesForVirtualService(nodeWithExtended(cg), virtualServiceWithExactMatchingOnHeaderForJWTClaims,
serviceRegistry, nil, 8080, gatewayNames, route.RouteOptions{})
xdstest.ValidateRoutes(t, routes)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(len(routes)).To(Equal(1))
g.Expect(len(routes[0].GetMatch().GetHeaders())).To(Equal(0))
g.Expect(routes[0].GetMatch().GetDynamicMetadata()[0].GetFilter()).To(Equal(filters.EnvoyJwtFilterName))
g.Expect(routes[0].GetMatch().GetDynamicMetadata()[0].GetInvert()).To(BeFalse())
g.Expect(routes[0].GetMatch().GetDynamicMetadata()[1].GetFilter()).To(Equal(filters.EnvoyJwtFilterName))
g.Expect(routes[0].GetMatch().GetDynamicMetadata()[1].GetInvert()).To(BeTrue())
})

t.Run("for virtual service with regex matching on header", func(t *testing.T) {
g := NewWithT(t)
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})
Expand Down
2 changes: 1 addition & 1 deletion pilot/pkg/networking/grpcgen/lds.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
if err != nil {
log.Warnf("Invalid rule %v: %v", rule, err)
continue
Expand Down
9 changes: 8 additions & 1 deletion pilot/pkg/networking/plugin/authn/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
if filter != nil {
return []*hcm.HttpFilter{filter}
}
return nil
}
res := []*hcm.HttpFilter{}
if filter := b.applier.JwtFilter(); filter != nil {
if filter := b.applier.JwtFilter(false, false); filter != nil {
res = append(res, filter)
}
forSidecar := b.proxy.Type == model.SidecarProxy
Expand Down
1 change: 1 addition & 0 deletions pilot/pkg/networking/plugin/authz/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func NewBuilder(actionType ActionType, push *model.PushContext, proxy *model.Pro
option := builder.Option{
IsCustomBuilder: actionType == Custom,
UseFilterState: useFilterState,
UseExtendedJwt: proxy.SupportsEnvoyExtendedJwt(),
}
selectionOpts := model.WorkloadSelectionOpts{
Namespace: proxy.ConfigNamespace,
Expand Down
2 changes: 1 addition & 1 deletion pilot/pkg/security/authn/policy_applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

// AuthNFilter returns the (authn) HTTP filter to enforce the underlying authentication policy.
// It may return nil, if no authentication is needed.
Expand Down
13 changes: 10 additions & 3 deletions pilot/pkg/security/authn/v1beta1/policy_applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ func NewPolicyApplier(rootNamespace string,
}
}

func (a v1beta1PolicyApplier) JwtFilter() *hcm.HttpFilter {
func (a v1beta1PolicyApplier) JwtFilter(useExtendedJwt, clearRouteCache bool) *hcm.HttpFilter {
if len(a.processedJwtRules) == 0 {
return nil
}

filterConfigProto := convertToEnvoyJwtConfig(a.processedJwtRules, a.push)
filterConfigProto := convertToEnvoyJwtConfig(a.processedJwtRules, a.push, useExtendedJwt, clearRouteCache)

if filterConfigProto == nil {
return nil
Expand Down Expand Up @@ -203,7 +203,7 @@ func (a v1beta1PolicyApplier) InboundMTLSSettings(
// Each rule is expected corresponding to one JWT issuer (provider).
// The behavior of the filter should reject all requests with invalid token. On the other hand,
// if no token provided, the request is allowed.
func convertToEnvoyJwtConfig(jwtRules []*v1beta1.JWTRule, push *model.PushContext) *envoy_jwt.JwtAuthentication {
func convertToEnvoyJwtConfig(jwtRules []*v1beta1.JWTRule, push *model.PushContext, useExtendedJwt, clearRouteCache bool) *envoy_jwt.JwtAuthentication {
if len(jwtRules) == 0 {
return nil
}
Expand All @@ -226,6 +226,13 @@ func convertToEnvoyJwtConfig(jwtRules []*v1beta1.JWTRule, push *model.PushContex
ForwardPayloadHeader: jwtRule.OutputPayloadToHeader,
PayloadInMetadata: jwtRule.Issuer,
}
if useExtendedJwt {
provider.PayloadInMetadata = filters.EnvoyJwtFilterPayload
provider.NormalizePayloadInMetadata = &envoy_jwt.JwtProvider_NormalizePayload{
SpaceDelimitedClaims: []string{"scope", "permission"},
}
provider.ClearRouteCache = clearRouteCache
}

for _, claimAndHeader := range jwtRule.OutputClaimToHeaders {
provider.ClaimToHeaders = append(provider.ClaimToHeaders, &envoy_jwt.JwtClaimToHeader{
Expand Down
4 changes: 2 additions & 2 deletions pilot/pkg/security/authn/v1beta1/policy_applier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ func TestJwtFilter(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
istiotest.SetForTest(t, &features.JwksFetchMode, c.jwksFetchMode)
if got := NewPolicyApplier("root-namespace", c.in, nil, push).JwtFilter(); !reflect.DeepEqual(c.expected, got) {
if got := NewPolicyApplier("root-namespace", c.in, nil, push).JwtFilter(false, false); !reflect.DeepEqual(c.expected, got) {
t.Errorf("got:\n%s\nwanted:\n%s", spew.Sdump(got), spew.Sdump(c.expected))
}
})
Expand Down Expand Up @@ -1243,7 +1243,7 @@ func TestConvertToEnvoyJwtConfig(t *testing.T) {

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := convertToEnvoyJwtConfig(c.in, push); !reflect.DeepEqual(c.expected, got) {
if got := convertToEnvoyJwtConfig(c.in, push, false, false); !reflect.DeepEqual(c.expected, got) {
t.Errorf("got:\n%s\nwanted:\n%s\n", spew.Sdump(got), spew.Sdump(c.expected))
}
})
Expand Down
3 changes: 2 additions & 1 deletion pilot/pkg/security/authz/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var rbacPolicyMatchNever = &rbacpb.Policy{
type Option struct {
IsCustomBuilder bool
UseFilterState bool
UseExtendedJwt bool
}

// Builder builds Istio authorization policy to Envoy filters.
Expand Down Expand Up @@ -218,7 +219,7 @@ func (b Builder) build(policies []model.AuthorizationPolicy, action rbacpb.RBAC_
b.logger.AppendError(fmt.Errorf("skipped nil rule %s", name))
continue
}
m, err := authzmodel.New(rule)
m, err := authzmodel.New(rule, b.option.UseExtendedJwt)
if err != nil {
b.logger.AppendError(multierror.Prefix(err, fmt.Sprintf("skipped invalid rule %s:", name)))
continue
Expand Down
30 changes: 26 additions & 4 deletions pilot/pkg/security/authz/matcher/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func MetadataStringMatcher(filter, key string, m *matcher.StringMatcher) *matche
}

// MetadataListMatcher creates a metadata list matcher for the given path keys and value.
func MetadataListMatcher(filter string, keys []string, value *matcher.StringMatcher) *matcher.MetadataMatcher {
func MetadataListMatcher(filter string, keys []string, value *matcher.StringMatcher, useExtendedJwt bool) *matcher.MetadataMatcher {
listMatcher := &matcher.ListMatcher{
MatchPattern: &matcher.ListMatcher_OneOf{
OneOf: &matcher.ValueMatcher{
Expand All @@ -59,13 +59,35 @@ func MetadataListMatcher(filter string, keys []string, value *matcher.StringMatc
})
}

return &matcher.MetadataMatcher{
out := &matcher.MetadataMatcher{
Filter: filter,
Path: paths,
Value: &matcher.ValueMatcher{
}
if useExtendedJwt {
out.Value = &matcher.ValueMatcher{
MatchPattern: &matcher.ValueMatcher_OrMatch{
OrMatch: &matcher.OrMatcher{
ValueMatchers: []*matcher.ValueMatcher{
{
MatchPattern: &matcher.ValueMatcher_ListMatch{
ListMatch: listMatcher,
},
},
{
MatchPattern: &matcher.ValueMatcher_StringMatch{
StringMatch: value,
},
},
},
},
},
}
} else {
out.Value = &matcher.ValueMatcher{
MatchPattern: &matcher.ValueMatcher_ListMatch{
ListMatch: listMatcher,
},
},
}
}
return out
}
2 changes: 1 addition & 1 deletion pilot/pkg/security/authz/matcher/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestMetadataListMatcher(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
want := getWant(tc.want)
actual := MetadataListMatcher("istio_authn", []string{"key1", "key2"}, StringMatcher("*"))
actual := MetadataListMatcher("istio_authn", []string{"key1", "key2"}, StringMatcher("*"), false)
if !cmp.Equal(want, actual, protocmp.Transform()) {
t.Errorf("want %s, but got %s", want.String(), actual.String())
}
Expand Down
Loading

0 comments on commit d4d1475

Please sign in to comment.