For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Access token validation
Validate tokens that API clients already hold by checking the token signature against Auth0’s signing keys.
Protect a route by validating an access token that the client already holds. Kgateway checks the token signature against the Auth0 signing keys and rejects requests that do not carry a valid token, instead of redirecting them to a login page. Use this flow for API clients, which cannot follow a browser redirect.
Before you begin
Complete the Auth0 setup page. This flow needs the Auth0 application, the test user, the Backend, and the BackendConfigPolicy that it creates, and it needs the Auth0 API whose Identifier the tokens carry in the aud claim.
Unlike the authorization code flow, this flow does not need the client secret in a Kubernetes Secret, because the gateway never exchanges an authorization code. It also works over plain HTTP, because it does not use cookies.
Configure access token validation
Create a GatewayExtension that tells the gateway how to validate tokens, and a TrafficPolicy that enforces it on a route.
-
Create a GatewayExtension for JWT validation. The
issuermust match the token’sissclaim from Auth0.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: GatewayExtension metadata: name: auth0-jwt namespace: kgateway-system spec: jwt: providers: - name: auth0 issuer: https://YOUR_AUTH0_DOMAIN/ jwks: remote: backendRef: group: gateway.kgateway.dev kind: Backend name: auth0 namespace: kgateway-system url: https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json audiences: - YOUR_API_AUDIENCE EOFField Description nameA required, unique name for the provider. The resource is rejected without it. issuerMust match the issclaim in your tokens exactly. Auth0 derivesissfrom your Auth0 domain and includes the trailing slash. Decode a real token and read itsissclaim rather than assuming.jwks.remote.backendRefThe network path that the gateway uses to fetch the signing keys. This is the Backendfor Auth0, so the JWKS endpoint does not have to be reachable from outside the cluster.jwks.remote.urlThe JWKS URL. Kgateway connects through backendRef, and uses this value for the request path andHostheader.audiencesThe accepted values of the audclaim. A token is rejected with a403response if none of its audiences match. Use the Identifier of the Auth0 API that you created in Auth0 setup, not the Management API. Auth0 puts theaudiencevalue from the token request into this claim, so the two must agree. You can decode a token and check itsaudclaim at jwt.io. -
Create a TrafficPolicy that references the JWT GatewayExtension. Make sure that the TrafficPolicy is in the same namespace as the HTTPRoute that it targets.
kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: TrafficPolicy metadata: name: auth0-jwt-policy namespace: httpbin spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: httpbin jwtAuth: extensionRef: name: auth0-jwt namespace: kgateway-system EOF -
Confirm that the TrafficPolicy is attached.
kubectl get TrafficPolicy auth0-jwt-policy -n httpbin -o yamlIn the
status.ancestorssection of the output, confirm that theAcceptedandAttachedconditions are bothTrue. An empty status means that the policy did not attach to anything.- message: Policy accepted reason: Valid status: "True" type: Accepted - message: Attached to all targets reason: Attached status: "True" type: Attached
Verify
Use the verification steps below to confirm that the access token validation flow works.
-
Confirm the JWKS URI. Auth0 always serves it at
/.well-known/jwks.jsonon your Auth0 domain, and it must match thejwks.remote.urlfield that you set on theGatewayExtension.https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json -
Verify that a request without a token is rejected.
curl -vi "http://$INGRESS_GW_ADDRESS:8080/headers" -H "host: www.example.com"Example output:
< HTTP/1.1 401 Unauthorized -
Obtain a token from Auth0 with the
passwordgrant. Request the token from the same Auth0 address that you set as theissueron theGatewayExtension, and pass the API Identifier as theaudienceso that the token carries it in theaudclaim.export TOKEN=$(curl -s -X POST "https://YOUR_AUTH0_DOMAIN/oauth/token" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "[email protected]" \ -d "password=YOUR_PASSWORD" \ -d "grant_type=password" \ -d "audience=YOUR_API_AUDIENCE" \ | jq -r .access_token)Note
If your tenant has more than one database connection, add
-d "connection=YOUR_CONNECTION_NAME"to the token request, or set the Default Directory on the application as described in Auth0 setup. -
Confirm that the token’s
issandaudclaims match yourGatewayExtension. Decode the payload.echo $TOKEN | jq -rR 'split(".")[1] | @base64d' | jq '{iss, aud}'Example output. If
auddoes not include your API Identifier, check theaudiencevalue that you passed to the token endpoint.{ "iss": "https://YOUR_AUTH0_DOMAIN/", "aud": ["https://my-api.example.com"] } -
Send a request with the token in the
Authorizationheader.curl -vi "http://$INGRESS_GW_ADDRESS:8080/headers" \ -H "host: www.example.com" \ -H "Authorization: Bearer $TOKEN"A successful response shows the headers from the httpbin app.
< HTTP/1.1 200 OKA
403response means that the token is valid but itsaudclaim does not match theaudienceslist. A401response means that the token is missing, expired, or signed by an issuer that does not matchissuer.
Cleanup
You can remove the resources that you created in this guide.kubectl delete TrafficPolicy auth0-jwt-policy -n httpbin
kubectl delete GatewayExtension auth0-jwt -n kgateway-systemTo remove Auth0 and the shared resources, see the Cleanup section of the Auth0 setup page.