Skip to content
Ashish.
All posts
Diagram showing Kong API Gateway validating JWTs via JWKS and propagating headers to upstream services.
6 min readDevelopmentPlatform Engineers, Backend DevelopersFeatured#kong#oidc#jwt#api-gateway#authentication#security#backend

API Gateway OIDC: Kong and Friends

Implement OIDC authentication in Kong API Gateway, covering JWT validation, JWKS caching, and upstream header propagation.

By Ashish KumarPart 6 of Identity Gateways & Legacy Integration

Implementing OpenID Connect (OIDC) in an API gateway like Kong requires understanding that the gateway does not authenticate the user. The Identity Provider (IdP)—such as Auth0, Okta, or Keycloak—does that. Kong’s role is strictly verification: it must confirm that a presented JSON Web Token (JWT) was signed by a trusted key and has not expired. The mechanism hinges on two operations: fetching the public key from the issuer’s JSON Web Key Set (JWKS) and caching it efficiently to avoid latency spikes on every request.

The Verification Mechanism

When a client sends a request to Kong, it includes a Bearer token in the Authorization header. Kong’s OIDC or JWT plugin extracts this token and parses its header. The header contains a kid (Key ID) field, which identifies which specific public key was used to sign the token.

Kong then checks its internal cache for the public key corresponding to that kid. If the key is present, Kong verifies the cryptographic signature of the JWT. If the signature is valid and the claims (such as exp for expiration) are within acceptable bounds, Kong considers the request authenticated. If the key is missing from the cache, Kong makes a synchronous HTTP GET request to the IdP’s JWKS endpoint. Note that the .well-known/openid-configuration endpoint is the Discovery Document, which contains the jwks_uri field; the actual JWKS endpoint is a separate URI specified in that discovery response.

This design means Kong is stateless regarding the user session. It does not store user data. It only stores the cryptographic material needed to validate tokens. This separation of concerns allows Kong to scale horizontally, but it introduces a dependency on the IdP’s availability during key fetches.

Technical diagram showing the flow of a JWT through Kong API Gateway. The client sends a request with an Authorization header. Kong extracts the kid, checks local cache, fetches from JWKS if missing, validates signature, and forwards to upstream. Clean, architectural style, bl…

JWKS Caching and Key Rotation

The most common failure mode in OIDC integration is improper JWKS caching. If Kong fetches the JWKS on every request, the IdP becomes a bottleneck. If Kong caches the JWKS forever, it fails when the IdP rotates signing keys.

Kong’s plugins generally rely on their own TTL configuration parameters (e.g., config.jwks_cache_ttl) rather than strictly following IdP HTTP headers like Cache-Control or ETag. Administrators must configure these TTLs to balance freshness against performance. If the IdP returns a Cache-Control header, Kong may respect it if explicitly configured to do so, but the primary control mechanism is the plugin's internal TTL setting.

However, key rotation can happen outside of standard cache windows. An IdP might rotate keys due to a security incident or a scheduled maintenance window, issuing a new kid before the old cache TTL expires. To handle this, Kong must be configured to check for key changes more frequently than the JWT’s validity period, or rely on strict TTL settings that align with IdP rotation policies.

Some implementations use a background worker that periodically refreshes the JWKS, independent of request traffic. This ensures that when a new token arrives with a new kid, the key is already in the cache. If the key is not found, Kong can either reject the request (fail-closed) or fetch it synchronously (fail-open, but with latency). For high-security environments, fail-closed is preferred; for high-availability systems, a short synchronous fetch with a fallback to a stale cache might be acceptable.

Upstream Header Propagation

Authentication is only half the problem. The backend service needs to know who the user is. Kong solves this by mapping JWT claims to HTTP headers. This process, known as header propagation, transforms the cryptographic validation into actionable context for the upstream application.

Kong’s OIDC plugin allows you to specify which claims from the JWT should be added to the request headers before forwarding to the upstream service. For example, you can map the sub (subject) claim to X-User-ID, the email claim to X-User-Email, and a custom roles claim to X-User-Roles.

This mapping is not automatic. You must define the mapping in the plugin configuration. Kong strips sensitive information from the JWT payload and only includes the mapped fields. This prevents accidental leakage of internal claims. The upstream service then trusts these headers because they were validated by Kong. If the upstream service receives a request with X-User-ID, it can assume that Kong has already verified the signature and expiration of the token containing that ID. The efficiency of this process relies heavily on the performance of the underlying jwks cache, ensuring that header propagation does not incur repeated network latency for key resolution.

Configuration Walkthrough

Consider a scenario where we are using Kong Gateway with an IdP hosted at https://auth.example.com. We want to protect a service at https://api.example.com.

First, we define the Service and Route. This is standard Kong configuration.

http POST http://kong-admin:8001/services name=api-backend url=https://api.example.com
 
http POST http://kong-admin:8001/services/api-backend/routes name=api-route paths=/app

Next, we attach the OIDC plugin to the service. The openid-connect plugin is designed for interactive login flows (Authorization Code Flow), involving session management and redirects. It is distinct from stateless token validation.

http POST http://kong-admin:8001/services/api-backend/plugins \
  name=openid-connect \
  config.discovery=https://auth.example.com/.well-known/openid-configuration \
  config.client_id=your-client-id \
  config.client_secret=your-client-secret \
  config.redirect_uris=http://localhost:8000/callback

Note that for pure JWT validation (where the client already has a token), you should use the jwt plugin instead, which is simpler and focused solely on validation.

For the jwt plugin, the configuration looks like this:

http POST http://kong-admin:8001/services/api-backend/plugins \
  name=jwt \
  config.claims_to_verify=exp \
  config.key_claim_name=kid

Here, claims_to_verify specifies which claims must be present and valid. key_claim_name tells Kong which claim in the JWT header points to the key identifier (typically kid), which Kong uses to look up the matching credential registered on a Consumer via the Admin API. Unlike the openid-connect plugin, the jwt plugin does not fetch keys from a remote JWKS endpoint.

Finally, to propagate claims, use the openid-connect plugin's built-in claim-to-header mapping, since the jwt plugin does not expose validated claims for use by other plugins like request-transformer.

http POST http://kong-admin:8001/services/api-backend/plugins \
  name=openid-connect \
  config.upstream_headers_claims=sub,email \
  config.upstream_headers_names=X-User-ID,X-User-Email

This configuration instructs Kong to take the value of the sub claim from the validated token and add it as a header X-User-ID to the request forwarded to api.example.com.

Tradeoffs and Operational Considerations

The primary tradeoff in this setup is complexity versus security. Implementing OIDC correctly requires managing the lifecycle of keys. If the IdP rotates keys, and Kong’s cache is stale, validation fails. Conversely, if Kong fetches the JWKS on every request, performance degrades.

Platform engineers must monitor the health of the JWKS endpoint. Kong provides metrics for the OIDC plugin, including the number of cache hits and misses. A sudden spike in cache misses indicates either a key rotation event or a misconfiguration in the TTL settings from the plugin configuration.

Additionally, consider the impact of network latency. If the IdP is in a different region, the initial JWKS fetch can add significant latency to the first request after a cache expiry. Pre-warming the cache or using a CDN to cache the JWKS endpoint can mitigate this.

Ultimately, Kong acts as a secure bridge. It validates the cryptographic integrity of the token and passes the identity context upstream. The security of the system depends on the correct configuration of this bridge, particularly the caching strategy for the public keys. Without careful management of JWKS caching, the gateway becomes either a bottleneck or a security risk.

Conclusion

Integrating OIDC with Kong involves more than just pasting a configuration; it requires a detailed understanding of key management and caching mechanics. By leveraging Kong’s ability to cache JWKS and propagate validated claims, you create a reliable, stateless authentication layer that scales horizontally while maintaining strict security boundaries. Always monitor cache hit rates and key rotation events to ensure your gateway remains both secure and performant.

Related posts