Skip to content

JWT provider configuration missing when multiple JWT Claim-Based Authorization SecurityPolicies are present #7295

@nfarhadian

Description

@nfarhadian

Description:

When multiple SecurityPolicy resources with OIDC+ JWT configuration are applied to different HTTPRoutes, only the first route’s JWT provider is rendered in the Envoy configuration.

As a result, requests to the second domain fail with the following error:

Failed JWT authentication: Wrong requirement_name: httproute/test/domain2/rule/1/match/0/domain2_example_com. It should be one of [httproute/test/domain1/rule/0/match/0/domain1_example_com]

Expected behavior:
Each HTTPRoute with its own SecurityPolicy should have a corresponding JWT provider entry in the Envoy configuration (i.e., both domain1 and domain2 providers should appear under envoy.filters.http.jwt_authn).

Actual behavior:
Only the first domain’s JWT provider appears in the generated Envoy configuration, while the second domain is missing entirely.


Repro steps:

  1. Create two HTTPRoute objects, e.g.:

    • domain1.example.com
    • domain2.example.com
  2. Attach two separate SecurityPolicy objects (one for each route) that each define:

    • An OIDC provider
    • A unique cookie name for access token
    • A unique JWT provider name

    Example:

    apiVersion: gateway.envoyproxy.io/v1alpha1
    kind: SecurityPolicy
    metadata:
      name: domain1-policy
    spec:
      targetRef:
        group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: domain1
      oidc:
        clientID: shared-oidc-client
        clientSecret:
          kind: Secret
          name: oidc-secret
        cookieNames:
          accessToken: AccessTokenDomain1
        refreshToken: true
        forwardAccessToken: true
        logoutPath: https://domain1.example.com/ztna/logout
        provider:
          issuer: https://sso.example.com/realms/myrealm
        redirectURL: https://domain1.example.com/ztna/callback
      jwt:
        optional: true
        providers:
        - extractFrom:
            cookies:
            - AccessTokenDomain1
          issuer: https://sso.example.com/realms/myrealm
          name: domain1-jwt
          remoteJWKS:
            uri: https://sso.example.com/realms/myrealm/protocol/openid-connect/certs
      authorization:
        defaultAction: Deny
        rules:
        - action: Allow
          name: allow
          principal:
            jwt:
              claims:
              - name: resource_access.ztna.roles
                valueType: StringArray
                values: [domain1-access]
              provider: domain1-jwt

    Repeat for domain2 with its own cookie (AccessTokenDomain2) and provider name (domain2-jwt).

  3. Deploy both routes and apply the policies.

  4. Observe that:

    • Authentication works for domain1.example.com
    • Requests to domain2.example.com fail with the above “Wrong requirement_name” error.
  5. Inspect the Envoy config via egctl config envoy-proxy all <PODNAME> -n <NAMESPACE>.
    You’ll find only one entry under the JWT providers section:

    "providers": {
      "httproute/test/domain1/rule/0/match/0/domain1_example_com/domain1-jwt": {
        "forward": true,
        "fromCookies": ["AccessTokenDomain1"],
        "issuer": "https://sso.example.com/realms/myrealm",
        "remoteJwks": {
          "httpUri": {
            "uri": "https://sso.example.com/realms/myrealm/protocol/openid-connect/certs"
          }
        }
      }
    }

    — while no corresponding provider is defined for domain2.


Environment:

  • Envoy Gateway version: v1.5.3
  • Envoy proxy version: v1.35.3
  • Kubernetes version: v1.34.1

P.S. I'm not sure if this bug happens if I don't use OIDC, but it seems bug is about JWT security policy.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions