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

The Header Cert Authentication plugin authenticates API calls by using client certificates provided in HTTP headers, instead of relying on traditional TLS termination. This approach is particularly useful in scenarios where TLS traffic is terminated outside of Kong Gateway such as at an external CDN or load balancer and the client certificate is passed along in an HTTP header for subsequent validation.

Important: To use this plugin, you must add certificate authority (CA) Certificates. Set them up before configuring the plugin.

How the Header Cert Auth plugin works

This plugin lets Kong Gateway authenticate API calls using client certificates received in HTTP headers, rather than through traditional TLS termination. This occurs in scenarios where TLS traffic is not terminated at Kong Gateway, but rather at an external CDN or load balancer, and the client certificate is preserved in an HTTP header for further validation.

The Header Cert Authentication plugin is similar to the mTLS Auth plugin. However, the mTLS plugin is only designed for traditional TLS termination, while the Header Cert Auth plugin also provides support for client certificates in headers.

The Header Cert Auth plugin extracts the client certificate from the HTTP header and validates it against the configured CA list. If the certificate is valid, the plugin maps the certificate to a Consumer based on the common name (CN) field.

The plugin validates the certificate provided against the configured CA list based on the requested Route or Gateway Service:

  • If the certificate is not trusted or has expired, the response is HTTP 401 TLS certificate failed verification.
  • If a valid certificate is not presented (including when requests are not sent to the HTTPS port), the response is HTTP 401 No required TLS certificate was sent.
  • However, if the config.anonymous option is configured on the plugin, an anonymous Consumer is used, and the request is allowed to proceed.

The plugin can be configured to only accept certificates from trusted IP addresses, as specified by the trusted_ips Kong Gateway config option. This ensures that Kong Gateway can trust the header sent from the source and provides L4 level of security.

Important: Incomplete or improper configuration of the Header Cert Authentication plugin can compromise the security of your upstream service.

For instance, enabling the option to bypass origin verification can allow malicious actors to inject fake certificates, as Kong Gateway won’t be able to verify the authenticity of the header. This can downgrade the security level of the plugin, making your upstream service vulnerable to attacks. Before using this plugin in production, carefully evaluate and configure the plugin according to your specific use case and security requirements.

This plugin’s static priority is lower than all other authentication plugins, allowing other auth plugins (for example, Basic Auth) to secure the source first. This ensures that the source is secured by multiple layers of authentication by providing L7 level of security.

Header size

Sending certificates in headers may exceed header size limits in some environments. You can configure Kong Gateway to accept larger headers by configuring the Nginx header buffer parameter in kong.conf. For example:

nginx_proxy_large_client_header_buffers=8 24k

Or via an environment variable:

export KONG_NGINX_PROXY_LARGE_CLIENT_HEADER_BUFFERS=8 24k

Client certificate request

The send_ca_dn option isn’t supported in this plugin. This is used in mutual TLS authentication, where the server sends the list of trusted CAs to the client, and the client then uses this list to select the appropriate certificate to present. In this case, since the plugin doesn’t do TLS handshakes and only parses the client certificate from the header, it isn’t applicable.

The same applies to SNI functionality. The plugin can verify the certificate without needing to know the specific hostname or domain being accessed. The plugin’s authentication logic is decoupled from the TLS handshake and SNI, so it doesn’t need to rely on SNI to function correctly.

The format specified in the config.certificate_header_format parameter defines how a certificate should be passed in a request.

  • When set to base64_encoded, only the base64-encoded body of the certificate should be sent (excluding the BEGIN CERTIFICATE and END CERTIFICATE delimiters).
  • When using url_encoded, the entire certificate, including the BEGIN CERTIFICATE and END CERTIFICATE delimiters, should be provided.

For example, given the certificate_header_name of x-client-cert, a base64_encoded example would look like the following:

x-client-cert: MIIDbDCCAdSgAwIBAgIUa...

A url_encoded example would look like the following:

x-client-cert: -----BEGIN%20CERTIFICATE-----%0AMIIDbDCCAdSgAwIBAgIUa...-----END%20CERTIFICATE-----

Manual mappings between Certificate and Consumer objects

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 can manually assign one or more subject names to the Consumer entity 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.

You can create a Consumer mapping with either of the following:

  • The /consumers/{consumer}/header-cert-auth Admin API endpoint
  • decK by specifying header_cert_auth_credentials in the configuration like the following:

    consumers:
    - custom_id: my-consumer
      username: {consumer}
      header_cert_auth_credentials:
      - id: bda09448-3b10-4da7-a83b-2a8ba6021f0c
        subject_name: test@example.com
    

The following table describes how Consumer mapping parameters work for the Header Cert Auth plugin:

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 Gateway’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 Admin API: UUID of the Certificate Authority (CA).

If using declarative configuration: Full PEM-encoded CA certificate.

The provided CA UUID or full CA 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 config.skip_consumer_lookup is set to true:

  1. Manual mappings with subject_name matching the certificate’s SAN or CN (in that order) and ca_certificate = {issuing authority of the client certificate}
  2. Manual mappings with subject_name matching the certificate’s SAN or CN (in that order) and ca_certificate = NULL
  3. If config.consumer_by is not null, Consumer with username and/or id matching the certificate’s SAN or CN (in that order)
  4. The config.anonymous Consumer (if set)

Note: Matching stops as soon as the first successful match is found.

Upstream headers

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 Gateway.
  • X-Consumer-Custom-ID: The custom_id of the Consumer (if set).
  • X-Consumer-Username: The username of the Consumer (if set).
  • X-Credential-Identifier: The identifier of the credential (only if the Consumer is not the anonymous Consumer).
  • X-Anonymous-Consumer: Is set to true if authentication fails, and the anonymous 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 Admin API and retrieve more information about the Consumer.

When config.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: The distinguished name of the client certificate
  • X-Client-Cert-San: The SAN of the client certificate

Once config.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 and create allowed or denied groups of users using the same certificate property being set in config.authenticated_group_by.

Troubleshooting authentication failure

When authentication fails, the client doesn’t 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 Gateway’s error logs under the [header-cert-auth] filter.

FAQs

No, the client only needs to send the target’s certificate encoded in a header. Kong Gateway will validate the certificate, but it requires a high level of trust that the WAF/LB is the only entrypoint to the Kong Gateway proxy. The Header Cert Auth plugin will provide an option to secure the source, but additional layers of security are always preferable. Network level security (so that Kong Gateway only accepts requests from WAF - IP allow/deny mechanisms) and application-level security (Basic Auth or Key Auth plugins to authenticate the source first) are examples of multiple layers of security that can be applied.

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!