Add mutual TLS authentication based on client-supplied or server-supplied certificate, and on the configured trusted CA list. Automatically maps certificates to consumers based on the common name field.
Configuration Reference
This plugin is compatible with DB-less mode.
In DB-less mode, you configure Kong Gateway declaratively. Therefore, the Admin API is mostly read-only. The only tasks it can perform are all related to handling the declarative config, including:
- Setting a target's health status in the load balancer
- Validating configurations against schemas
- Uploading the declarative configuration using the
/config
endpoint
Example plugin configuration
Parameters
Here's a list of all the parameters which can be used in this plugin's configuration:
Form Parameter | Description |
---|---|
name
required Type: string |
The name of the plugin, in this case mtls-auth . |
instance_name
optional Type: string |
An optional custom name to identify an instance of the plugin, for example Useful when running the same plugin in multiple contexts, for example, on multiple services. |
service.name or service.id
optional Type: string |
The name or ID of the service the plugin targets. Set one of these parameters if adding the plugin to a service through the top-level Not required if using |
route.name or route.id
optional Type: string |
The name or ID of the route the plugin targets. Set one of these parameters if adding the plugin to a route through the top-level Not required if using |
enabled
optional Type: boolean Default value: |
Whether this plugin will be applied. |
config.anonymous
optional Type: string |
An optional string (consumer UUID or username) value to use as an “anonymous” consumer if authentication fails. If empty (default null), the request fails with an authentication failure |
config.consumer_by
optional Type: array of string elements Default value: |
Whether to match the subject name of the client-supplied certificate against consumer’s |
config.ca_certificates
required Type: array of string elements |
List of CA Certificates strings to use as Certificate Authorities (CA) when validating a client certificate.
At least one is required but you can specify as many as needed. The value of this array is comprised
of primary keys ( |
config.skip_consumer_lookup
required Type: boolean Default value: |
Skip consumer lookup once certificate is trusted against the configured CA list. |
config.authenticated_group_by
optional Type: string Default value: |
Certificate property to use as the authenticated group. Valid values are |
config.revocation_check_mode
optional Type: string Default value: |
Controls client certificate revocation check behavior. Valid values are |
config.http_timeout
Type: number Default value: |
HTTP timeout threshold in milliseconds when communicating with the OCSP server or downloading CRL. |
config.cert_cache_ttl
Type: number Default value: |
The length of time in milliseconds between refreshes of the revocation check status cache. |
config.cache_ttl
required Type: number Default value: |
Cache expiry time in seconds. |
config.http_proxy_host
semi-optional Type: string |
The HTTP hostname or IP address of a proxy. Use this setting with
Required if |
config.http_proxy_port
semi-optional Type: string |
The TCP port of the HTTP proxy. Required if |
config.https_proxy_host
semi-optional Type: string |
The HTTPS hostname or IP address of a proxy. Use this setting with
Required if |
config.https_proxy_port
semi-optional Type: string |
The TCP port of the HTTPS proxy. Required if |
config.send_ca_dn
optional Type: boolean Default value: |
Sends the distinguished names (DN) of the configured CA list in the TLS handshake message. |
config.allow_partial_chain
required Type: boolean Default value: |
Allow certificate verification with only an intermediate certificate. When this is enabled, you don’t need to upload the full chain to Kong Certificates. |
Usage
In order to authenticate the consumer, it must provide a valid certificate and complete mutual TLS handshake with Kong.
The plugin validates the certificate provided against the configured CA list based on the requested route or service.
- If the certificate is not trusted or has expired, the response will be
HTTP 401 TLS certificate failed verification
. - If consumer did not present a valid certificate (this includes requests not
sent to the HTTPS port), then the response will be
HTTP 401 No required TLS certificate was sent
. The exception is if theconfig.anonymous
option was configured on the plugin, in which case the anonymous consumer is used and the request is allowed to proceed.
Client certificate request
Client certificates are requested in the ssl_certificate_by_lua
phase where Kong does not
have access to route
and workspace
information. Due to this information gap, Kong asks for
the client certificate by default on every handshake if the mtls-auth
plugin is configured on any route or service.
In most cases, the failure of the client to present a client certificate is not going to affect subsequent
proxying if that route or service does not have the mtls-auth
plugin applied. The exception is where
the client is a desktop browser, which prompts the end user to choose the client cert to send and
lead to user experience issues rather than proxy behavior problems. To improve this situation,
Kong builds an in-memory map of SNIs from the configured Kong routes that should present a client
certificate. To limit client certificate requests during handshake while ensuring the client
certificate is requested when needed, the in-memory map is dependent on the routes in
Kong having the SNIs attribute set. When any routes do not have SNIs set, Kong must request
the client certificate during every TLS handshake:
- On every request irrespective of Workspace when the plugin is enabled in global Workspace scope.
- On every request irrespective of Workspace when the plugin is applied at the service level and one or more of the routes do not have SNIs set.
- On every request irrespective of Workspace when the plugin is applied at the route level and one or more routes do not have SNIs set.
- On specific requests only when the plugin is applied at the route level and all routes have SNIs set.
SNIs must be set for all routes that mutual TLS authentication uses.
Adding certificate authorities
To use this plugin, you must add certificate authority (CA) certificates. These are
stored in a separate ca_certificates
store rather than the main certificates store because
they do not require private keys. To add one, obtain a PEM-encoded copy of your CA certificate
and POST it to /ca_certificates
:
The id
value returned can now be used for mTLS plugin configurations or consumer mappings.
Sending the CA DNs during TLS handshake
By default, Kong Gateway won’t send the CA DN list during the TLS handshake. More specifically,
the certificate_authorities
in the CertificateRequest message is empty.
In some cases, the client may need this certificate_authorities
to guide
certificate selection. Setting config.send_ca_dn
to true
will add the
CA certificates configured in the config.ca_certificate
to the lists of
the corresponding SNIs.
As mentioned in Client certificate request,
due to the phase gap, Kong Gateway doesn’t know the route information in the
ssl_certificate_by_lua
phase, which is decided in the later access
phase.
Therefore Kong Gateway builds an in-memory map of SNIs. The CA DN list will eventually
be associated with the SNIs. If multiple mtls-auth
plugins with different
config.ca_certificate
are associated to the same SNI, the CA DNs will be
merged. For example:
- When the plugin is enabled in the global Workspace scope, the CA DNs are associated with a special SNI, “*”.
- When the plugin is applied at the service level, the CA DNs are associated with every SNI of every route to this service. If a route has no SNIs set, then the CA DNs are associated with a special SNI, “*”.
- When the plugin is applied at the route level, the CA DNs are associated with every SNI configured on this route. If the route has no SNIs set, then the CA DNs are associated with a special SNI, “*”.
During the mTLS handshake, if the client sends a SNI in the ClientHello message and the SNI is found in the in-memory map of SNIs, then the corresponding CA DN list is sent in CertificatRequest message.
If the client doesn’t send SNIs in the ClientHello message or the SNI sent is unknown to Kong Gateway, then the CA DN list associated with “*” is sent only when the client certificate is requested.
Create manual mappings between certificate and consumer object
Sometimes, you might not want to use automatic consumer lookup, or you have certificates that contain a field value not directly associated with consumer objects. In those situations, you may manually assign one or more subject names to the consumer object for identifying the correct consumer.
Note: Subject names refer to the certificate’s Subject Alternative Names (SAN) or Common Name (CN). CN is only used if the SAN extension does not exist.
Parameters for manual mapping
Form Parameter | Default | Description |
---|---|---|
id required for declarative config |
none | UUID of the consumer-mapping. Required if adding mapping using declarative configuration, otherwise generated automatically by Kong’s Admin API. |
subject_name required |
none | The Subject Alternative Name (SAN) or Common Name (CN) that should be mapped to consumer (in order of lookup). |
ca_certificate optional |
none | If using the Kong Admin API: UUID of the Certificate Authority (CA). If using declarative configuration: Full PEM-encoded CA certificate. The provided CA UUID or full certificate has to be verifiable by the issuing certificate authority for the mapping to succeed. This is to help distinguish multiple certificates with the same subject name that are issued under different CAs. If empty, the subject name matches certificates issued by any CA under the corresponding config.ca_certificates . |
Matching behaviors
After a client certificate has been verified as valid, the consumer object is determined in the following order, unless skip_consumer_lookup
is set to true
:
- Manual mappings with
subject_name
matching the certificate’s SAN or CN (in that order) andca_certificate = <issuing authority of the client certificate>
- Manual mappings with
subject_name
matching the certificate’s SAN or CN (in that order) andca_certificate = NULL
- If
config.consumer_by
is not null, consumer withusername
and/orid
matching the certificate’s SAN or CN (in that order) - The
config.anonymous
consumer (if set)
Note: Matching stops as soon as the first successful match is found.
When a client has been authenticated, the plugin appends some headers to the request before proxying it to the upstream service, so that you can identify the consumer in your code:
X-Consumer-ID
: The ID of the consumer in Kong.X-Consumer-Custom-ID
: Thecustom_id
of the consumer (if set).X-Consumer-Username
: Theusername
of the consumer (if set).X-Credential-Identifier
: The identifier of the credential (only if the consumer is not theanonymous
consumer).X-Anonymous-Consumer
: Is set totrue
if authentication fails, and theanonymous
consumer is set instead.
You can use this information on your side to implement additional logic.
You can use the X-Consumer-ID
value to query the Kong Admin API and retrieve
more information about the consumer.
When skip_consumer_lookup
is set to true
, consumer lookup is skipped and instead of appending aforementioned headers, the plugin appends the following two headers
X-Client-Cert-Dn
, distinguished name of the client certificateX-Client-Cert-San
, SAN of the client certificate
Once skip_consumer_lookup
is applied, any client with a valid certificate can access the Service/API.
To restrict usage to only some of the authenticated users, also add the ACL plugin (not covered here) and create
allowed or denied groups of users using the same
certificate property being set in authenticated_group_by
.
Troubleshooting
When authentication fails, the client does not have access to any details that explain the
failure. The security reason for this omission is to prevent malicious reconnaissance.
Instead, the details are recorded inside Kong’s error logs under the [mtls-auth]
filter.
Changelog
Kong Gateway 3.0.x
- The deprecated
X-Credential-Username
header has been removed.
Kong Gateway 2.8.1.1
- Introduced certificate revocation list (CRL) and OCSP server support with the
following parameters:
http_proxy_host
,http_proxy_port
,https_proxy_host
, andhttps_proxy_port
.