You are browsing documentation for an outdated plugin version.
Mutual TLS client authentication
The OpenID Connect plugin supports mutual TLS (mTLS) client authentication with the IdP. When mTLS authentication is enabled, Kong 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:
-
token
-
introspection
-
revocation
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.
Requirements for an mTLS client auth configuration
Auth server configuration
The feature requires the IdP to be enabled to use mTLS and X.509 client certificate authentication. For configuring this in Keycloak, refer to the Keycloak configuration section below. For different auth servers, refer to their documentation to configure this functionality.
Kong configuration
- Set the client authentication methods. Refer to the configuration reference sections:
- Configure the client certificate ID as a value for the
tls_client_auth_cert_id
field as described in the configuration reference.
Certificates
For mTLS connections, create a certificate and key pair for Kong Gateway to use when connecting to the IdP:
http -f post :8001/certificates cert@crt.pem key@key.pem
SSL verify
The configuration option tls_client_auth_ssl_verify
controls whether the server (IdP) certificate is verified.
When set to true
(the default value), ensure trusted certificate and verify depth are appropriately configured so that the IdP’s server certificate is trusted by Kong and the handshake can be performed successfully.
Demo
Prerequisites
Follow these prerequisites to set up a demo Keycloak app and a Kong service and route for testing mTLS client auth.
In most cases, the OpenID Connect plugin relies on a third party identity provider (IdP). The examples in this guide use Keycloak as a sample IdP.
Expand the following sections to configure Keycloak and Kong Gateway.
Configure Keycloak
All the *.test
domains in the following examples point to the localhost
(127.0.0.1
and/or ::1
).
We use Keycloak as the identity provider in the following examples, but the steps will be similar in other standard identity providers. If you encounter difficulties during this phase, refer to the Keycloak documentation.
- Create a confidential client
kong
withprivate_key_jwt
authentication and configure Keycloak to download the public keys from [the OpenID Connect Plugin JWKS endpoint][json-web-key-set]:
-
Create another confidential client
service
withclient_secret_basic
authentication. For this client, Keycloak will auto-generate a secret similar to the following:cf4c655a-0622-4ce6-a0de-d3353ef0b714
. Enable the client credentials grant for the client:
-
(Optional) Create another confidential client
cert-bound
with settings similar to theservice
client created previously. From the Advanced tab, enable the OAuth 2.0 Mutual TLS Certificate Bound Access Tokens Enabled toggle. -
(Optional, to test mTLS Client Authentication) Create another confidential client
client-tls-auth
with settings similar to theservice
client created above. From the Credentials tab, select the X509 Certificate Client Authenticator and fill the Subject DN field so that it matches the Kong client certificate’s, e.g.:CN=JohnDoe, OU=IT
. -
(Optional, to test Demonstrating Proof-of-Possession Client Authentication) Create another confidential client
client-dpop-auth
with settings similar to theservice
client created above. From the Advanced tab, enable theOAuth 2.0 DPoP Bound Access Tokens Enabled toggle. - Create a verified user with the name:
john
and the non-temporary password:doe
that can be used with the password grant:
Alternatively you can download the exported Keycloak configuration, and use it to configure the Keycloak. Please refer to Keycloak import documentation for more information.
You need to modify Keycloak standalone.xml
configuration file, and change the socket binding from:
<socket-binding name="https" port="${jboss.https.port:8443}"/>
to
<socket-binding name="https" port="${jboss.https.port:8440}"/>
The Keycloak default https
port conflicts with the default Kong TLS proxy port,
and that can be a problem if both are started on the same host.
Note: The mTLS Client Authentication, along with the proof of possession feature that validates OAuth 2.0 Mutual TLS Certificate Bound Access Tokens, both require configuring Keycloak to validate client certificates with mTLS using the
--https-client-auth=request
option, and to configure TLS appropriately, including adding the trusted client certificates to the truststore. For more information, refer to the Keycloak documentation.
Configure Kong Gateway
-
Create a service:
curl -i -X POST http://localhost:8001/services \ --data "name=openid-connect" \ --data "url=https://httpbin.konghq.com/anything"
-
Create a route:
curl -i -X POST http://localhost:8001/services/openid-connect/routes \ --data "name=openid-connect" \ --data "paths[]=/"
Set up mTLS for the OIDC plugin
Using the Keycloak and Kong Gateway configuration from the prerequisites, set up an instance of the OpenID Connect plugin.
For the demo, we’re going to set up the following:
- Issuer, client ID: Settings that connect the plugin to your IdP (in this case, the sample Keycloak app).
-
client_auth
: Must use TLS (tls_client_auth
). - Auth methods: For demo purposes, we use the password grant, but you can use any supported auth method.
-
tls_client_auth_cert_id
: Pass the ID of the certificate object you created via/certificates
.
With all of the above in mind, let’s test out mTLS client auth with the password grant, using Keycloak as the IdP.
Enable the OpenID Connect plugin on the openid-connect
service:
Test mTLS client auth
Access the service using the password
auth method.
Kong will access the IdP’s token endpoint using the mTLS Client Authentication with the configured certificate:
curl http://localhost:8000/openid-connect --user john:doe
If successful, you should receive a 200 status code:
HTTP/1.1 200 OK