Skip to content

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Page as Markdown

    

OAuth2 with separate JWKS backend

By default, the OAuth2 provider uses the same backendRef for both the OAuth2 token endpoint and the JWKS endpoint. However, some identity providers such as Amazon Cognito host these endpoints on different domains.

The jwksBackendRef field in OAuth2JWTConfig lets you specify a separate backend for fetching JWKS, enabling more flexible network routing and certificate management.

When to use a separate JWKS backend

  • When the JWKS endpoint is on a different domain than the token endpoint.
  • When you need different network policies or TLS settings for JWKS fetching.
  • When the JWKS endpoint requires different authentication or authorization.

Before you begin

    1. Follow the Get started guide to install kgateway.

    2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

    3. Get the external address of the gateway and save it in an environment variable.

      export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
      echo $INGRESS_GW_ADDRESS  

  1. Complete the OAuth2/OIDC guide.

Configure separate backends

To configure separate backends for the token endpoint and JWKS fetching, update your existing OAuth2 GatewayExtension with a jwksBackendRef field.

Step 0: Save your existing GatewayExtension

Before making changes, save the current GatewayExtension YAML to a file:

kubectl get gatewayextension keycloak-oauth2 -n kgateway-system -o yaml > gatewayextension-oauth2.yaml

This ensures you have a backup and can modify the saved file directly.

Step 1: Verify your primary backend

Your existing GatewayExtension already has a backendRef that points to your OAuth2 provider’s token endpoint. This remains unchanged. The primary backend is used for:

  • Token endpoint
  • Authorization endpoint
  • End session endpoint

Step 2: Add a JWKS backend

Add the jwksBackendRef field to your GatewayExtension to specify a dedicated backend for JWKS fetching:

jwksBackendRef:
  kind: Backend
  group: gateway.kgateway.dev
  name: cognito-jwks
If you don’t set jwksBackendRef, the gateway uses the primary backendRef for JWKS requests, maintaining backward compatibility.

Step 3: Define the JWKS Backend resource

Create a Backend resource that points to your JWKS endpoint:

apiVersion: gateway.kgateway.dev/v1alpha1
kind: Backend
metadata:
  name: cognito-jwks
  namespace: kgateway-system
spec:
  type: Static
  static:
    hosts:
    - host: cognito-idp.us-east-1.amazonaws.com
      port: 443

Step 4: Apply the updated configuration

Apply the GatewayExtension and Backend resources:

kubectl apply -f gatewayextension-oauth2.yaml
kubectl apply -f cognito-jwks-backend.yaml

Example: Amazon Cognito

The following example shows how to configure jwksBackendRef for Amazon Cognito. For more information on setting up Cognito as an OIDC provider, see the Amazon Cognito documentation.

The fields in the example come from your Cognito user pool configuration:

  • jwksURI: https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/jwks.json
  • tokenEndpoint: https://cognito-idp.<region>.amazonaws.com/oauth2/token
  • authorizationEndpoint: https://cognito-idp.<region>.amazonaws.com/oauth2/authorize
apiVersion: gateway.kgateway.dev/v1alpha1
kind: GatewayExtension
metadata:
  name: oauth-two-backends
  namespace: kgateway-system
spec:
  oauth2:
    backendRef:
      kind: Backend
      group: gateway.kgateway.dev
      name: cognito-token
    tokenEndpoint: https://cognito-idp.us-east-1.amazonaws.com/token
    authorizationEndpoint: https://cognito-idp.us-east-1.amazonaws.com/authorize
    credentials:
      clientID: your-client-id
      clientSecretRef:
        name: oauth-client-secret
    redirectURI: https://example.com/oauth2/redirect
    scopes: ["openid", "email"]
    jwt:
      jwksURI: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123/.well-known/jwks.json
      jwksBackendRef:
        kind: Backend
        group: gateway.kgateway.dev
        name: cognito-jwks
      accessToken:
        audiences:
          - your-client-id

Backend Definitions

apiVersion: gateway.kgateway.dev/v1alpha1
kind: Backend
metadata:
  name: cognito-token
  namespace: kgateway-system
spec:
  type: Static
  static:
    hosts:
    - host: cognito-idp.us-east-1.amazonaws.com
      port: 443
---
apiVersion: gateway.kgateway.dev/v1alpha1
kind: Backend
metadata:
  name: cognito-jwks
  namespace: kgateway-system
spec:
  type: Static
  static:
    hosts:
    - host: cognito-idp.us-east-1.amazonaws.com
      port: 443

Verify the configuration

After deploying the GatewayExtension, verify that the JWKS is fetched from the correct backend.

Send a request with a valid token:

curl -vik http://$INGRESS_GW_ADDRESS:8080/headers \
  -H "host: www.example.com:8080" \
  --header "Authorization: Bearer $TOKEN"

Expected output:

< HTTP/1.1 200 OK

If the JWKS is fetched correctly, you should see a 200 OK response.

Backward Compatibility

The jwksBackendRef field is optional. If not specified, the gateway uses the parent backendRef for JWKS fetching, maintaining compatibility with existing configurations.

Cleanup

You can remove the resources that you created in this guide.

Delete the GatewayExtension and Backend resources that you created in this guide.

kubectl delete gatewayextension oauth-two-backends -n kgateway-system
kubectl delete backend cognito-token -n kgateway-system
kubectl delete backend cognito-jwks -n kgateway-system
Was this page helpful?