Not able to read nested claim in AuthoriazationPolicy

Searching online it seems that reading nested claims was implemented with Istio 1.8, I am using Istio 1.10.0.

Given the following kube yaml:

---
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: myapp-sso
  namespace: mynamespace
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: myapp
  jwtRules:
    - issuer: "REDACTED"
      audiences: ["REDACTED"]
      jwksUri: "https://login.microsoftonline.com/common/discovery/keys"
      
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: authorize-myapp-poc-read
  namespace: mynamespace
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: myapp
  action: ALLOW
  rules:
    - to:
      - operation:
          methods: ["GET"]
          paths: ["*"]
      when:
        - key: request.auth.claims[roles]
          values: ["env.read"]

---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: authorize-myapp-poc-write
  namespace: mynamespace
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: myapp
  action: ALLOW
  rules:
    - to:
      - operation:
          methods: ["DELETE", "GET", "POST", "PUT", "PATCH"]
          paths: ["*"]
      when:
        - key: request.auth.claims[roles]
          values: ["env.write"]

A JWT token containing the following claim roles should give me read access or write access with “env.write”.

{
  "aud": "REDACTED",
  "iss": "REDACTED",
  "iat": 1638376109,
  "nbf": 1638376109,
  "exp": 1638380009,
  "aio": "UkVEQUNURUQK",
  "appid": "REDACTED",
  "appidacr": "1",
  "idp": "REDACTED",
  "oid": "REDACTED",
  "rh": "REDACTED",
  "roles": [
    "env.read"
  ],
  "sub": "REDACTED",
  "tid": "REDACTED",
  "uti": "REDACTED",
  "ver": "1.0"
}

I get a 403 unauthorized when I submit a GET (or PUT etc for env.read).

I was able to configure my gateway’s logs to debug and what I am seeing looks to be what is expected.

2021-12-01T17:59:47.037031Z	debug	envoy http	[C552] new stream
2021-12-01T17:59:47.037128Z	debug	envoy http	[C552][S14242082210848494550] request headers complete (end_stream=false):
':authority', 'REDACTED'
':path', '/api/v1/namespaces'
':method', 'GET'
'authorization', 'Bearer REDACTED'
'content-type', 'application/json'
'user-agent', 'PostmanRuntime/7.28.4'
'accept', '*/*'
'cache-control', 'no-cache'
'postman-token', '9881325f-f852-454f-a8bd-281b3bc2bf0f'
'accept-encoding', 'gzip, deflate, br'
'connection', 'keep-alive'
'content-length', '93'
2021-12-01T17:59:47.037184Z	debug	envoy jwt	Called Filter : setDecoderFilterCallbacks
2021-12-01T17:59:47.037245Z	debug	envoy jwt	Called Filter : decodeHeaders
2021-12-01T17:59:47.037265Z	debug	envoy jwt	Prefix requirement '/' matched.
2021-12-01T17:59:47.037274Z	debug	envoy jwt	extract authorizationBearer 
2021-12-01T17:59:47.037306Z	debug	envoy jwt	origins-0: JWT authentication starts (allow_failed=false), tokens size=1
2021-12-01T17:59:47.037314Z	debug	envoy jwt	origins-0: startVerify: tokens size 1
2021-12-01T17:59:47.037319Z	debug	envoy jwt	origins-0: Parse Jwt REDACTED
2021-12-01T17:59:47.037472Z	debug	envoy jwt	origins-0: Verifying JWT token of issuer REDACTED
2021-12-01T17:59:47.037552Z	debug	envoy jwt	origins-0: JWT token verification completed with: OK
2021-12-01T17:59:47.037571Z	debug	envoy jwt	Jwt authentication completed with: OK
2021-12-01T17:59:47.037601Z	debug	envoy filter	AuthenticationFilter::decodeHeaders with config
policy {
  origins {
    jwt {
      issuer: "REDACTED"
    }
  }
  origin_is_optional: true
  principal_binding: USE_ORIGIN
}
skip_validate_trust_domain: true
2021-12-01T17:59:47.037611Z	debug	envoy filter	No method defined. Skip source authentication.
2021-12-01T17:59:47.037618Z	debug	envoy filter	Validating request path /api/v1/namespaces for jwt issuer: "REDACTED"
2021-12-01T17:59:47.037705Z	debug	envoy filter	ProcessJwtPayload: json object is {"aio":"REDACTED","appid":"REDACTED","appidacr":"1","aud":"REDACTED","exp":1638384262,"iat":1638380362,"idp":"REDACTED","iss":"REDACTED","nbf":1638380362,"oid":"REDACTED","rh":"REDACTED","roles":["env.read"],"sub":"REDACTED","tid":"REDACTED","uti":"REDACTED","ver":"1.0"}
2021-12-01T17:59:47.037730Z	debug	envoy filter	JWT validation succeeded
2021-12-01T17:59:47.037745Z	debug	envoy filter	Set principal from origin: REDACTED
2021-12-01T17:59:47.037748Z	debug	envoy filter	Origin authenticator succeeded
2021-12-01T17:59:47.037852Z	debug	envoy filter	Saved Dynamic Metadata:
fields {
  key: "request.auth.audiences"
  value {
    string_value: "REDACTED"
  }
}
fields {
  key: "request.auth.claims"
  value {
    struct_value {
      fields {
        key: "aio"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "appid"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "appidacr"
        value {
          list_value {
            values {
              string_value: "1"
            }
          }
        }
      }
      fields {
        key: "aud"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "idp"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "iss"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "oid"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "rh"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "roles"
        value {
          list_value {
            values {
              string_value: "env.read"
            }
          }
        }
      }
      fields {
        key: "sub"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "tid"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "uti"
        value {
          list_value {
            values {
              string_value: "REDACTED"
            }
          }
        }
      }
      fields {
        key: "ver"
        value {
          list_value {
            values {
              string_value: "1.0"
            }
          }
        }
      }
    }
  }
}
fields {
  key: "request.auth.principal"
  value {
    string_value: "REDACTED"
  }
}
fields {
  key: "request.auth.raw_claims"
  value {
    string_value: "{\"appidacr\":\"1\",\"ver\":\"1.0\",\"oid\":\"REDACTED\",\"sub\":\"REDACTED\",\"uti\":\"REDACTED\",\"exp\":1638384262,\"iat\":1638380362,\"tid\":\"REDACTED\",\"iss\":\"REDACTED\",\"aio\":\"REDACTED\",\"aud\":\"REDACTED\",\"nbf\":1638380362,\"appid\":\"REDACTED\",\"roles\":[\"env.read\"],\"idp\":\"REDACTED\",\"rh\":\"REDACTED\"}"
  }
}
2021-12-01T17:59:47.037889Z	debug	envoy router	[C552][S14242082210848494550] cluster 'outbound|443||mynamespace.myapp.svc.cluster.local' match for URL '/api/v1/namespaces'
2021-12-01T17:59:47.037952Z	debug	envoy router	[C552][S14242082210848494550] router decoding headers:
':authority', 'REDACTED'
':path', '/api/v1/namespaces'
':method', 'GET'
':scheme', 'https'
'content-type', 'application/json'
'user-agent', 'PostmanRuntime/7.28.4'
'accept', '*/*'
'cache-control', 'no-cache'
'postman-token', '9881325f-f852-454f-a8bd-281b3bc2bf0f'
'accept-encoding', 'gzip, deflate, br'
'content-length', '93'
'x-forwarded-for', '10.11.229.35'
'x-forwarded-proto', 'https'
'x-envoy-internal', 'true'
'x-request-id', 'c1fe2233-f0d8-4317-82ee-ef2db4eb27ef'
'x-envoy-decorator-operation', 'mynamespace.myapp.svc.cluster.local:443/api/*'
'x-envoy-peer-metadata', 'ChQKDkFQUF9DT05UQUlORVJTEgIaAAoaCgpDTFVTVEVSX0lEEgwaCkt1YmVybmV0ZXMKGQoNSVNUSU9fVkVSU0lPThIIGgYxLjEwLjAK0gUKBkxBQkVMUxLHBSrEBQoXCgNhcHASEBoOaXN0aW8tb3BlcmF0b3IKKAobYXBwLmt1YmVybmV0ZXMuaW8vY29tcG9uZW50EgkaB2luZ3Jlc3MKJQobYXBwLmt1YmVybmV0ZXMuaW8vbWFuYWdlZEJ5EgYaBEhlbG0KMgoWYXBwLmt1YmVybmV0ZXMuaW8vbmFtZRIYGhZpc3Rpby1vcGVyYXRvci1pbmdyZXNzCi0KGWFwcC5rdWJlcm5ldGVzLmlvL3BhcnQtb2YSEBoOaXN0aW8tb3BlcmF0b3IKJQoZYXBwLmt1YmVybmV0ZXMuaW8vdmVyc2lvbhIIGgZ2MC4wLjIKEwoFY2hhcnQSChoIZ2F0ZXdheXMKHQoNaGVsbS5zaC9jaGFydBIMGgp1ZHAtYWRkb25zChQKCGhlcml0YWdlEggaBlRpbGxlcgo2CilpbnN0YWxsLm9wZXJhdG9yLmlzdGlvLmlvL293bmluZy1yZXNvdXJjZRIJGgd1bmtub3duCiIKBWlzdGlvEhkaF21ldGFkYXRhLWluZ3Jlc3NnYXRld2F5ChkKDGlzdGlvLmlvL3JldhIJGgdkZWZhdWx0CjAKG29wZXJhdG9yLmlzdGlvLmlvL2NvbXBvbmVudBIRGg9JbmdyZXNzR2F0ZXdheXMKIQoRcG9kLXRlbXBsYXRlLWhhc2gSDBoKNTU4N2Q5ODY1YwoSCgdyZWxlYXNlEgcaBWlzdGlvCjwKH3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLW5hbWUSGRoXbWV0YWRhdGEtaW5ncmVzc2dhdGV3YXkKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0ChEKA3NoYRIKGgg2MTRlYTkyYwoiChdzaWRlY2FyLmlzdGlvLmlvL2luamVjdBIHGgVmYWxzZQoaCgdNRVNIX0lEEg8aDWNsdXN0ZXIubG9jYWwKMgoETkFNRRIqGihtZXRhZGF0YS1pbmdyZXNzZ2F0ZXdheS01NTg3ZDk4NjVjLTZ3N3ZtChsKCU5BTUVTUEFDRRIOGgxpc3Rpby1zeXN0ZW0KYAoFT1dORVISVxpVa3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2lzdGlvLXN5c3RlbS9kZXBsb3ltZW50cy9tZXRhZGF0YS1pbmdyZXNzZ2F0ZXdheQoXChFQTEFURk9STV9NRVRBREFUQRICKgAKKgoNV09SS0xPQURfTkFNRRIZGhdtZXRhZGF0YS1pbmdyZXNzZ2F0ZXdheQ=='
'x-envoy-peer-metadata-id', 'router~100.112.87.225~metadata-ingressgateway-5587d9865c-6w7vm.istio-system~istio-system.svc.cluster.local'
'x-envoy-attempt-count', '1'
'x-b3-traceid', '12ff4c3389a3ea240de1fc39e35f9a7a'
'x-b3-spanid', '0de1fc39e35f9a7a'
'x-b3-sampled', '0'
'x-envoy-original-path', '/api/v1/namespaces'
2021-12-01T17:59:47.037967Z	debug	envoy pool	queueing stream due to no available connections
2021-12-01T17:59:47.037972Z	debug	envoy pool	trying to create new connection
2021-12-01T17:59:47.037977Z	debug	envoy pool	creating a new connection
2021-12-01T17:59:47.038046Z	debug	envoy client	[C553] connecting
2021-12-01T17:59:47.038055Z	debug	envoy connection	[C553] connecting to 100.112.23.29:5000
2021-12-01T17:59:47.038157Z	debug	envoy connection	[C553] connection in progress
2021-12-01T17:59:47.038190Z	debug	envoy jwt	Called Filter : decodeData
2021-12-01T17:59:47.038217Z	debug	envoy http	[C552][S14242082210848494550] request end stream
2021-12-01T17:59:47.038225Z	debug	envoy jwt	Called Filter : decodeData
2021-12-01T17:59:47.038786Z	debug	envoy connection	[C553] connected
2021-12-01T17:59:47.039703Z	debug	envoy client	[C553] connected
2021-12-01T17:59:47.039720Z	debug	envoy pool	[C553] attaching to next stream
2021-12-01T17:59:47.039725Z	debug	envoy pool	[C553] creating stream
2021-12-01T17:59:47.039734Z	debug	envoy router	[C552][S14242082210848494550] pool ready
2021-12-01T17:59:47.040746Z	debug	envoy router	[C552][S14242082210848494550] upstream headers complete: end_stream=false
2021-12-01T17:59:47.040796Z	debug	envoy http	[C552][S14242082210848494550] encoding headers via codec (end_stream=false):
':status', '403'
'content-length', '19'
'content-type', 'text/plain'
'date', 'Wed, 01 Dec 2021 17:59:46 GMT'
'server', 'istio-envoy'
'x-envoy-upstream-service-time', '2'
2021-12-01T17:59:47.040813Z	debug	envoy client	[C553] response complete
2021-12-01T17:59:47.040937Z	debug	envoy wasm	wasm log stats_outbound stats_outbound: [extensions/stats/plugin.cc:621]::report() metricKey cache hit , stat=12
2021-12-01T17:59:47.040948Z	debug	envoy wasm	wasm log stats_outbound stats_outbound: [extensions/stats/plugin.cc:621]::report() metricKey cache hit , stat=6
2021-12-01T17:59:47.040951Z	debug	envoy wasm	wasm log stats_outbound stats_outbound: [extensions/stats/plugin.cc:621]::report() metricKey cache hit , stat=10
2021-12-01T17:59:47.040954Z	debug	envoy wasm	wasm log stats_outbound stats_outbound: [extensions/stats/plugin.cc:621]::report() metricKey cache hit , stat=14
2021-12-01T17:59:47.040958Z	debug	envoy jwt	Called Filter : onDestroy
2021-12-01T17:59:47.040961Z	debug	envoy filter	Called AuthenticationFilter : onDestroy
2021-12-01T17:59:47.040966Z	debug	envoy pool	[C553] response complete
2021-12-01T17:59:47.040969Z	debug	envoy pool	[C553] saw upstream close connection
2021-12-01T17:59:47.040972Z	debug	envoy connection	[C553] closing data_to_write=0 type=1
2021-12-01T17:59:47.040975Z	debug	envoy connection	[C553] closing socket: 1
2021-12-01T17:59:47.041003Z	debug	envoy connection	[C553] SSL shutdown: rc=0
2021-12-01T17:59:47.041038Z	debug	envoy client	[C553] disconnect. resetting 0 pending requests
2021-12-01T17:59:47.041045Z	debug	envoy pool	[C553] client disconnected, failure reason: 
2021-12-01T17:59:47.041093Z	debug	envoy pool	[C553] destroying stream: 0 remaining

Judging by all of the documentation that I have been able to find, my authz policies should be working.

My Kube cluster has 3rd party JWT enabled (I do not know if that is a contributing factor).

I am still relatively new to Istio so any help pointing me into the right direction would be most appreciated!

@YangminZhu could you please check this.