Downstream mTLS Settings
Downstream mTLS settings control the client certificate requirements for end users connecting to Pomerium-managed routes. (To configure a client certificate presented by Pomerium to an upstream service, see the TLS Client Certificate setting.)
These settings are grouped in the YAML configuration file under the key downstream_mtls
.
Certificate Authority (CA)
CA is a bundle of PEM-encoded X.509 certificates that will be treated as trust anchors when verifying client certificates. Both root and intermediate CA certificates can be used as trust anchors.
Any per-route certificate authorities set using the (deprecated) TLS Downstream Client CA option will be added to this CA bundle.
The Subject Name of all configured CA certificates will be advertised in the initial TLS handshake, and so should not include any sensitive information.
The CA setting is required for downstream mTLS.
This setting previously used the config file keys client_ca
and client_ca_file
and the environment variables CLIENT_CA
and CLIENT_CA_FILE
.
How to configure
The CA bundle can be specified inline (with the ca
key or the DOWNSTREAM_MTLS_CA
environment variable) or as a path to a file on disk (with the ca_file
key or the DOWNSTREAM_MTLS_CA_FILE
environment variable). It is considered an error to specify both.
- Core
- Enterprise
- Kubernetes
Config file keys | Environment variables | Type |
---|---|---|
downstream_mtls.ca | DOWNSTREAM_MTLS_CA | string (base64-encoded PEM certificate bundle) |
downstream_mtls.ca_file | DOWNSTREAM_MTLS_CA_FILE | string (path to PEM certificate bundle) |
These settings are not configurable in the Enterprise Console.
The Ingress Controller does not support these settings.
Examples
downstream_mtls:
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk...
downstream_mtls:
ca_file: /path/to/trusted/CAs.pem
DOWNSTREAM_MTLS_CA=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk...
DOWNSTREAM_MTLS_CA_FILE=/path/to/trusted/CAs.pem
Certificate Revocation List (CRL)
CRL support is a beta feature.
Please test thoroughly with your client certificate deployment before enabling this feature in your production environment.
CRL is a bundle of PEM-encoded certificate revocation lists to be consulted during certificate validation. Any leaf certificates listed as revoked will not be trusted. (This setting cannot be used to revoke an intermediate CA certificate.) Delta CRLs are not supported.
Additionally, when Enforcement Mode is set to reject_connection
, any provided CRLs will be considered valid only for the time period between their thisUpdate
and nextUpdate
timestamps. If a provided CRL is no longer valid, no certificates from the corresponding CA will be trusted. When using CRLs in combination with this mode, you must be prepared to regularly update all provided CRLs.
How to configure
A CRL bundle can be specified inline (with the crl
key or the DOWNSTREAM_MTLS_CRL
environment variable) or as a path to a file on disk (with the crl_file
key or the DOWNSTREAM_MTLS_CRL_FILE
environment variable). It is considered an error to specify both.
- Core
- Enterprise
- Kubernetes
Config file keys | Environment variables | Type |
---|---|---|
downstream_mtls.crl | DOWNSTREAM_MTLS_CRL | string (base64-encoded PEM CRL bundle) |
downstream_mtls.crl_file | DOWNSTREAM_MTLS_CRL_FILE | string (path to PEM CRL bundle) |
These settings are not configurable in the Enterprise Console.
The Ingress Controller does not support these settings.
Examples
downstream_mtls:
crl: LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tCk...
downstream_mtls:
crl_file: /path/to/CRLs.pem
DOWNSTREAM_MTLS_CRL=LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tCk...
DOWNSTREAM_MTLS_CRL_FILE=/path/to/CRLs.pem
Enforcement Mode
Enforcement Mode controls Pomerium's behavior when a client does not present a trusted client certificate. There are three options:
policy_with_default_deny
— Pomerium will serve an HTML error page when making a request to any user-defined route without a trusted client certificate. (This is the default behavior.)Note that in this mode, client certificates are not required for internal Pomerium routes, such as the authenticate URL (if using the self-hosted authenticate service) or the /.pomerium/ page (the page showing details of a user's current login session).
Any requests without a trusted client certificate will be logged by the authorize service, with the deny reason
client-certificate-required
(if no certificate was presented) orinvalid-client-certificate
(if an untrusted or invalid certificate was presented).policy
— Pomerium will not require client certificates for any routes unless explicitly required by a route policy.This mode allows you to configure only certain routes to require a trusted client certificate. To configure a route to require client certificates, add a policy Deny rule with the
invalid_client_certificate
criterion. (See Pomerium Policy Language for more information.)As in the previous mode, Pomerium will serve an HTML error page for any routes where client certificates are required but no trusted certificate is presented, and likewise these requests will be logged by the authorize service.
reject_connection
— Pomerium will require a trusted client certificate during the initial TLS handshake. Any connection attempts that do not present a trusted client certificate will be rejected.Users will see a browser default error page. For example:
This matches the default behavior of many popular reverse proxies, such as Apache httpd and Caddy.
Note that in this mode, client certificates will be required even for internal Pomerium routes, such as the authenticate URL (if using the self-hosted authenticate service) and the /.pomerium/ page (the page showing details of a user's current login session). In particular, any upstream services that perform JWT verification will not be able to access the default JWKS endpoint. You may need to host your own JWKS endpoint, or provide some other means of distributing the JWT verification key(s).
This mode also adds a requirement that any configured CRL is valid only between its
thisUpdate
andnextUpdate
timestamps. If an invalid CRL is provided for a certain CA, no certificates issued by that CA will be allowed.Also note that in this mode, requests without a trusted client certificate will never reach the Pomerium authorize service, and so no record of these requests will be logged.
How to configure
- Core
- Enterprise
- Kubernetes
Config file keys | Environment variables | Type |
---|---|---|
downstream_mtls.enforcement | DOWNSTREAM_MTLS_ENFORCEMENT | string (one of policy_with_default_deny , policy , or reject_connection ) |
This setting is not configurable in the Enterprise Console.
The Ingress Controller does not support this setting.
Examples
downstream_mtls:
enforcement: reject_connection
DOWNSTREAM_MTLS_ENFORCEMENT=reject_connection
Match Subject Alt Names
Match Subject Alt Names can be used to add an additional constraint when validating client certificates: each certificate must contain a Subject Alternative Name (SAN) of a particular type, whose value matches the provided regular expression.
Client certificates satisfying at least one of the provided match conditions will be allowed.
Supported SAN types include:
dns
— a DNS nameemail
— an email address (this is therfc822Name
as specified in RFC 5280 §4.2.1.6)ip_address
— an IP address (either IPv4 or IPv6)uri
— a Uniform Resource Identifier (URI)
The provided regular expression must match against the entire SAN entry. The regular expressions use Google's RE2 syntax.
SAN IPv4 addresses will be expressed in dotted decimal notation (e.g. "127.0.0.1") when matching against the provided regular expression. SAN IPv6 addresses will be expressed as specified in RFC 5952.
How to configure
- Core
- Enterprise
- Kubernetes
Config file keys | Environment variables | Type |
---|---|---|
downstream_mtls.match_subject_alt_names | n/a | array of mappings from SAN type to regular expression |
This setting is not configurable in the Enterprise Console.
The Ingress Controller does not support this setting.
Examples
To require that all client certificates have a DNS SAN with a domain name ending in ".corp.example.com":
downstream_mtls:
match_subject_alt_names:
- dns: '.*\.corp\.example\.com'
To require that all client certificates have either a DNS SAN containing the string "beyondcorp" or an email address SAN with the domain "example.com":
downstream_mtls:
match_subject_alt_names:
- dns: '.*beyondcorp.*'
- email: '.*@example\.com'
Max Verify Depth
Max Verify Depth sets a limit on the depth of a certificate chain presented by the client. The depth is defined as the number of certificates in the verified trust chain, excluding the trust anchor. (The trust anchor can be any root or intermediate CA certificate included in the trusted CA bundle.) This limit does not override any pathLenConstraint
set within the CA certificates themselves (see RFC 5280 §4.2.1.9).
When set to 0, no specific limit is enforced.
For compatibility with previous Pomerium releases, the default is 1. That is, only certificates directly issued by a CA included in the trusted CA bundle are allowed.
The default value for this setting may change in a future Pomerium release.
The following diagram illustrates a CA setup with a root CA, an intermediate CA, and a second intermediate CA issued by the first intermediate CA:
In this scenario, with Max Verify Depth set to 1, only "Certificate A" would be allowed (as it is issued directly by the root CA). When set to 2, both "Certificate A" and "Certificate B" would be allowed, but not "Certificate C." When set to 3 or greater, then all of "Certificate A," "Certificate B," and "Certificate C" would be allowed.
Note that a client presenting "Certificate B" must also include the "Intermediate CA 1" certificate, as it is not part of the trusted CA bundle. Likewise, a client presenting "Certificate C" must also include both the "Intermediate CA 1" and "Intermediate CA 2" certificates.
How to configure
- Core
- Enterprise
- Kubernetes
Config file keys | Environment variables | Type |
---|---|---|
downstream_mtls.max_verify_depth | DOWNSTREAM_MTLS_MAX_VERIFY_DEPTH | unsigned integer |
This setting is not configurable in the Enterprise Console.
The Ingress Controller does not support this setting.
Examples
To allow client certificate chains including the leaf certificate and at most one client-supplied intermediate CA certificate (before a trusted root or intermediate CA):
downstream_mtls:
max_verify_depth: 2
DOWNSTREAM_MTLS_MAX_VERIFY_DEPTH=2
To remove the default limit:
downstream_mtls:
max_verify_depth: 0
DOWNSTREAM_MTLS_MAX_VERIFY_DEPTH=0