Related Documentation
Made by
Kong Inc.
Supported Gateway Topologies
hybrid db-less traditional
Supported Konnect Deployments
hybrid cloud-gateways serverless
Compatible Protocols
grpc grpcs http https

The OpenID Connect (OIDC) plugin lets you integrate Kong Gateway with an identity provider (IdP). This plugin can be used to implement Kong Gateway as a proxying OAuth 2.0 resource server (RS) and as an OpenID Connect relying party (RP) between the client and the upstream service.

What does OpenID Connect do?

OpenID Connect provides a way to form a federation with identity providers (IdPs). Identity providers are third parties that store account credentials. If an identity provider authenticates a user to an application, the application trusts that provider and allows access to the user. This shifts the responsibility of authentication from the application to the identity provider.

Besides delegating responsibility to an identity provider, OpenID Connect also makes single sign-on possible without storing any credentials on a user’s local machine.

What does Kong’s OpenID Connect plugin do?

The OpenID Connect plugin enables you to integrate OpenID Connect with Kong Gateway without having to write custom integrations. Instead of manually writing code for OpenID Connect within an upstream service, you can place Kong Gateway in front of the upstream service and have Kong Gateway handle authentication. This separation lets developers focus on the business logic within their application, easily swap out upstream services while preserving authentication at the front door, and effortlessly spread the same authentication to new upstream services.

Unlike other authentication types like Key Auth and Basic Auth, with OpenID Connect you don’t need to manage user credentials directly. Instead, you can offload the task to a trusted identity provider of your choice.

Supported flows and grants

The OpenID Connect plugin suits many different use cases and extends other plugins such as JWT (JSON Web Token), ACL, and 0Auth 2.0. The most common use case is the authorization code flow.

Authentication flows and grants

The OIDC plugin supports several types of credentials and grants. When this plugin is configured with multiple grants or flows, there is a hardcoded search order for the credentials:

  1. Session authentication
  2. JWT access token authentication
  3. Kong OAuth token authentication
  4. Introspection authentication
  5. User info authentication
  6. Refresh token grant
  7. Password grant (username and password)
  8. Client credentials grant
  9. Authorization code flow (with client secret or PKCE)

Once it finds a set of credentials, the plugin stops searching, and won’t look for any further credential types.

Multiple grants may share the same credentials. For example, both the password and client credentials grants can use basic authentication through the Authorization header.

Authorization code flow

The authorization code flow is the three-legged OAuth/OpenID Connect flow. The sequence diagram below describes the participants and their interactions for this usage scenario, including the use of session cookies:

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant idp as IdP
(e.g. Keycloak) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: HTTP request kong->>client: Redirect mobile app to IDP deactivate kong activate idp client->>idp: Request access and authentication
with client parameter Note left of idp: /auth
response_type=code,
scope=openid idp->>client: Login (ask for consent) client->>idp: /auth with user credentials (grant consent) idp->>client: Return authorization code and redirect Note left of idp: short-lived authcode activate kong client->>kong: HTTP redirect with authorization code deactivate client kong->>kong: Verify authorization code flow kong->>idp: Request ID token, access token, and refresh token Note left of idp: /token
client_id:client_secret
authcode idp->>idp: Authenticate client (Kong)
and validate authcode idp->>kong: Returns tokens Note left of idp: ID token, access token, and refresh token deactivate idp kong->>kong: Validate tokens Note right of kong: Cryptographic
signature validation,
expiry check
(OIDC Standard JWT validation) activate client kong->>client: Redirect with session cookie
having session ID (SID) Note left of kong: sid: cryptorandom bytes
(128 bits)
& HMAC protected client->>kong: Authenticated request with session cookie deactivate client kong->>kong: Verify session cookie Note right of kong: Retrieve encrypted tokens
from session store (redis) activate httpbin kong->>httpbin: Backend service request with tokens Note right of idp: Access token and ID token httpbin->>kong: Backend service response deactivate httpbin activate client kong->>client: HTTP response deactivate kong deactivate client

If using PKCE, the identity provider must contain the code_challenge_methods_supported object in the /.well-known/openid-configuration issuer discovery endpoint response, as required by RFC 8414. If it’s not included, the PKCE code_challenge query parameter won’t be sent.

Client credentials grant workflow

The client credentials grant is very similar to the password grant. The most important difference is that the plugin itself doesn’t try to authenticate, and instead forwards the credentials passed by the client to the identity server’s token endpoint.

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant idp as IdP
(e.g. Keycloak) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
basic authentication deactivate client kong->>kong: load basic
authentication credentials activate idp kong->>idp: IdP/token
with client credentials deactivate kong idp->>idp: authenticate client activate kong idp->>kong: return tokens deactivate idp kong->>kong: verify tokens activate httpbin kong->>httpbin: request with access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

Introspection authentication flow

As with JWT access token authentication, the introspection authentication relies on a bearer token that the client has already gotten from somewhere. The difference between introspection and stateless JWT authentication is that the plugin needs to call the introspection endpoint of the identity provider to find out whether the token is valid and active. This makes it possible to issue opaque tokens to the clients.

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant idp as IdP
(e.g. Keycloak) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with access token deactivate client kong->>kong: load access token activate idp kong->>idp: IdP/introspect with
client credentials and access token deactivate kong idp->>idp: authenticate client
and introspect access token activate kong idp->>kong: return introspection response deactivate idp kong->>kong: verify introspection response activate httpbin kong->>httpbin: request with
access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

JWT access token authentication flow

For legacy reasons, the stateless JWT Access Token authentication is named bearer (see config.auth_methods). Stateless authentication means that the signature verification uses the identity provider to publish public keys and the standard claims verification (such as exp or expiry). The client may receive the token directly from the identity provider or by other means.

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
access token deactivate client kong->>kong: load access token kong->>kong: verify signature kong->>kong: verify claims activate httpbin kong->>httpbin: request with
access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

Kong OAuth token authentication flow

The OpenID Connect plugin can verify the tokens issued by the OAuth 2.0 plugin. This is very similar to third party identity provider issued JWT access token authentication or introspection authentication:

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
access token deactivate client kong->>kong: load access token kong->>kong: verify kong
oauth token activate httpbin kong->>httpbin: request with
access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

Refresh token grant workflow

The refresh token grant can be used when the client has a refresh token available. There is a caveat with this: in general, identity providers only allow the refresh token grant to be executed with the same client that originally got the refresh token, and if there is a mismatch, it may not work. The mismatch is likely when the OpenID Connect plugin is configured to use one client, and the refresh token is retrieved with another.

The grant itself is very similar to the password grant and the client credentials grant:

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant idp as IdP
(e.g. Keycloak) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
refresh token deactivate client kong->>kong: load refresh token activate idp kong->>idp: IdP/token with
client credentials and
refresh token deactivate kong idp->>idp: authenticate client and
verify refresh token activate kong idp->>kong: return tokens deactivate idp kong->>kong: verify tokens activate httpbin kong->>httpbin: request with access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

Session authentication workflow

The OpenID Connect plugin can issue a session cookie that can be used for further session authentication. To make OpenID Connect issue a session cookie, you need to first authenticate with one of the other grants or flows that this plugin supports. For example, the authorization code flow demonstrates session authentication when it uses the redirect login action.

The session authentication portion of the flow works like this:

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
session cookie deactivate client kong->>kong: load session cookie kong->>kong: verify session activate httpbin kong->>httpbin: request with
access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

User info authentication flow

The user info authentication uses OpenID Connect standard user info endpoint to verify the access token. In most cases, you would use introspection authentication instead of user info, as introspection is meant for retrieving information from the token itself, whereas the user info endpoint is meant for retrieving information about the user to whom the token was given. The flow is almost identical to introspection authentication:

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant idp as IdP
(e.g. Keycloak) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
access token deactivate client kong->>kong: load access token activate idp kong->>idp: IdP/userinfo
with client credentials
and access token deactivate kong idp->>idp: authenticate client and
verify token activate kong idp->>kong: return user info
response deactivate idp kong->>kong: verify response
status code (200) activate httpbin kong->>httpbin: request with access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

Password grant workflow

Password grant is a legacy authentication grant. This is a less secure way of authenticating end users than the authorization code flow, because, for example, the passwords are shared with third parties.

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong) participant idp as IdP
(e.g. Keycloak) participant httpbin as Upstream
(upstream service,
e.g. httpbin) activate client activate kong client->>kong: Service with
basic authentication deactivate client kong->>kong: load
basic authentication
credentials activate idp kong->>idp: IdP/token with
client credentials and
password grant deactivate kong idp->>idp: authenticate client and
verify password grant activate kong idp->>kong: return tokens deactivate idp kong->>kong: verify tokens activate httpbin kong->>httpbin: request with access token httpbin->>kong: response deactivate httpbin activate client kong->>client: response deactivate kong deactivate client

Authorization

The OpenID Connect plugin has several options for performing coarse-grained authorization:

  1. Claims-based authorization
  2. ACL plugin authorization
  3. Consumer authorization

Claims-based authorization

Claims-based authorization uses a pair of options to manage claims verification during authorization. The pair can be any of:

  1. config.scopes_claim and config.scopes_required
  2. config.audience_claim and config.audience_required
  3. config.groups_claim and config.groups_required
  4. config.roles_claim and config.roles_required

For example, the first configuration option, config.groups_claim, points to a source, from which the value is retrieved and checked against the value of the second configuration option, config.groups_required.

Both the claim type and the required claim content take an array of string elements.

For the claim type (for example, config.groups_claim), the array is a list of JSON objects listed in nested order. The plugin uses the order of the items in the array to look up data in a JSON payload.

The value of a claim can be:

  • A space-separated string (common for scope claims)
  • An JSON array of strings (common for groups claims)
  • A simple value, such as a string

For example, let’s look at the following sample payload, where groups is nested inside user:

{
    "user": {
        "name": "alex",
        "groups": [
            "employee",
            "marketing"
        ]
    }
}

In this case, you would use config.groups_claim to traverse to the groups you need, where groups is the JSON object that contains the list of groups:

config:
  groups_claim:
  - user
  - groups

On the other hand, the config.*_required parameters are arrays that allow logical AND/OR types of checks:

  • AND: Space-separated values

    This claim has to have both employee AND marketing:

    config:
      groups_required:
      - employee marketing
    
  • OR: Values in separate array indices

    This claim has to have either employee OR marketing:

    config:
      groups_required:
      - employee
      - marketing
    

ACL plugin authorization

The OpenID Connect plugin can be integrated with the ACL plugin, which provides access control functionality in the form of allow and deny lists.

You can also pair ACL-based authorization with Kong Gateway Consumer authorization.

Consumer authorization

You can use Kong Gateway Consumers for authorization and dynamically map claim values to Consumers. This means that we restrict the access to only those that do have a matching Consumer. Consumers can have ACL groups attached to them and be further authorized with the ACL plugin.

Client authentication

Mutual TLS client authentication

The OpenID Connect plugin supports mutual TLS (mTLS) client authentication with the IdP. When mTLS authentication is enabled, Kong Gateway establishes mTLS connections with the IdP using the configured client certificate. You can use mTLS client authentication with the following IdP endpoints and corresponding flows:

For all these endpoints and for the flows supported, the plugin uses mTLS client authentication as the authentication method when communicating with the IdP, for example, to fetch the token from the token endpoint.

Financial-grade API (FAPI) v3.7+

The OpenID Connect plugin supports various features of the FAPI standard, aimed to protect APIs that expose high-value and sensitive data.

Specification

Description

Example

Pushed authorization requests (PAR) With PAR enabled, Kong Gateway (as the OAuth client) sends the payload of an authorization request to the IdP. As a result, it obtains a request_uri value. The client uses this value in a call to the authorization endpoint as a reference to obtain the authorization request payload data.

Use config.pushed_authorization_request_endpoint to enable PAR.
JWT-secured authorization requests (JAR) With JAR enabled, when sending requests to the authorization endpoint, Kong Gateway provides request parameters in a JSON Web Token (JWT) instead of using a query string. This allows for request data to be signed with JSON Web Signature (JWS).

Use config.require_signed_request_object to enable JAR.
JWT-secured authorization response mode (JARM) With JARM enabled, Kong Gateway requests the authorization server to return the authorization response parameters encoded in a JWT, which allows the response data to be signed with JSON Web Signature (JWS).

Set config.response_mode to any of the following values: query.jwt, form_post.jwt, fragment.jwt, jwt to enable JARM.
Certificate-bound access tokens Certificate-bound access tokens allow binding tokens to clients. This guarantees the authenticity of the token by verifying whether the sender is authorized to use the token for accessing protected resources.

Set config.proof_of_possession_mtls to strict and config.client_id to cert-bound to enable cert-bound access tokens.
Set up certificate-bound access tokens
Mutual TLS (mTLS) client authentication with certificate-bound access tokens When mTLS client authentication is enabled, Kong Gateway establishes mTLS connections with the IdP using the configured X.509 certificate as client credentials.

If the authorization server is configured to bind the client certificate with the issued access token, Kong Gateway can validate the access token using mTLS proof of possession.

Set config.client_auth to tls_client_auth and provide a certificate at config.tls_client_auth_cert_id to enable mTLS auth.
Set up mTLS client authentication

Set up certificate-bound access tokens
Demonstrating proof-of-possession (DPoP) Demonstrating Proof of Possession (DPoP) is an application-level mechanism for proving the sender’s ownership of OAuth access and refresh tokens. With DPoP, a client can prove the possession of a public/private key pair associated with a token by using a header. The header contains a signed JWT that includes a reference to the associated access token.

When DPoP is enabled, Kong Gateway validates the DPoP header in the request to ensure that the sender is authorized to use the access token.

Set config.proof_of_possession_dpop to strict to enable DPoP.
Demonstrating Proof-of-Possession

Certificate-bound access tokens

One of the main vulnerabilities of OAuth is bearer tokens. With OAuth, presenting a valid bearer token is enough proof to access a resource. This can create problems since the client presenting the token isn’t validated as the legitimate user that the token was issued to.

Certificate-bound access tokens can solve this problem by binding tokens to clients. This ensures the legitimacy of the token because the it requires proof that the sender is authorized to use a particular token to access protected resources.

Certificate-bound access tokens are supported by the following auth methods:

Session authentication is only compatible with certificate-bound access tokens when used along with one of the other supported authentication methods:

  • When the configuration option config.proof_of_possession_auth_methods_validation is set to false and other non-compatible methods are enabled, if a valid session is found, the proof of possession validation will only be performed if the session was originally created using one of the compatible methods.
  • If multiple openid-connect plugins are configured with the session auth method, we strongly recommend configuring different values of config.session_secret across plugin instances for additional security. This avoids sessions being shared across plugins and possibly bypassing the proof of possession validation.

To enable certificate-bound access for OpenID Connect:

  • Ensure that the auth server (IdP) that you’re using is set up to generate OAuth 2.0 Mutual TLS certificate-bound access tokens.
  • Use the proof_of_possession_mtls configuration option to ensure that the supplied access token belongs to the client by verifying its binding with the client certificate provided in the request.

See the cert-bound configuration example for more detail.

Demonstrating Proof-of-Possession (DPoP)

Demonstrating Proof-of-Possession (DPoP) is an alternative technique to the mutual TLS certificate-bound access tokens. Unlike its alternative, which binds the token to the mTLS client certificate, it binds the token to a JSON Web Key (JWK) provided by the client.

 
sequenceDiagram
    autonumber
    participant client as Client 
(e.g. mobile app) participant kong as API Gateway
(Kong Gateway) participant upstream as Upstream
(backend service,
e.g. httpbin) participant idp as Authentication Server
(e.g. Keycloak) activate client client->>client: generate key pair client->>idp: POST /oauth2/token
DPoP:$PROOF deactivate client activate idp idp-->>client: DPoP bound access token ($AT) activate client deactivate idp client->>kong: GET https://example.com/resource
Authorization: DPoP $AT
DPoP: $PROOF activate kong deactivate client kong->>kong: validate $AT and $PROOF kong->>upstream: proxied request
GET https://example.com/resource
Authorization: Bearer $AT deactivate kong activate upstream upstream-->>kong: upstream response deactivate upstream activate kong kong-->>client: response deactivate kong

You can use the Demonstrating Proof-of-Possession option without mTLS, and even with plain HTTP, although HTTPS is recommended for enhanced security.

When verification of the DPoP proof is enabled, Kong Gateway removes the DPoP header and changes the token type from dpop to bearer. This effectively downgrades the request to use a conventional bearer token, and allows an OAuth2 upstream without DPoP support to work with the DPoP token without losing the protection of the key binding mechanism.

DPoP is compatible with the following authentication methods:

Session authentication is only compatible with DPoP when used along with one of the other supported authentication methods. If multiple openid-connect plugins are configured with the session authentication method, we strongly recommend configuring different values of config.session_secret across plugin instances for additional security. This avoids sessions being shared across plugins and possibly bypassing the proof of possession validation.

To enable DPoP for OpenID Connect:

  • Ensure that the auth server (IdP) that you’re using has DPoP enabled.
  • Use the config.proof_of_possession_dpop configuration option to ensure that the supplied access token is bound to the client by verifying its association with the JWT provided in the request.

See the DPoP configuration example for more detail.

Debugging the OIDC plugin

If you have issues with the OIDC plugin, try the following debugging methods:

  1. Set the Kong Gateway log level to debug, and check the Kong Gateway error.log. You can filter the log with the keyword openid-connect.

  2. Set the OpenID Connect plugin to display errors by setting config.display_errors to true.

  3. Temporarily disable the OpenID Connect plugin verifications by setting the following parameters to false:
  4. Check what kinds of tokens the OpenID Connect plugin can receive by reviewing the following parameter configurations, and ensure that your token type is allowed:
  5. Session-related issues are often caused by large cookies. Try storing the session data in Redis or memcache, as that will make the session cookie much smaller. Set this up using config.session_storage.

  6. Try to eliminate indirection in the form of other gateways, load balancers, NATs, and so on, in front of Kong Gateway, as that makes it easier to find out where the problem is. If one of these other applications is causing issues, looking into using the following:

Supported identity providers

The plugin has been tested with several OpenID Connect providers:

As long as your provider supports OpenID Connect standards, the plugin should work, even if it is not specifically tested against it.

Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!