|
| 1 | +--- |
| 2 | +title: Mutual TLS stage |
| 3 | +authentik_version: "2025.6" |
| 4 | +authentik_preview: true |
| 5 | +authentik_enterprise: true |
| 6 | +toc_max_heading_level: 5 |
| 7 | +--- |
| 8 | + |
| 9 | +The Mutual TLS stage enables authentik to use client certificates to enroll and authenticate users. These certificates can be local to the device or available via PIV Smart Cards, Yubikeys, etc. |
| 10 | + |
| 11 | +Management of client certificates is out of the scope of this document. |
| 12 | + |
| 13 | +## Reverse-proxy configuration |
| 14 | + |
| 15 | +Using the Mutual TLS stage requires special configuration of any reverse proxy that is used in front of authentik, because the reverse-proxy interacts directly with the browser. |
| 16 | + |
| 17 | +- nginx |
| 18 | + - [Standalone nginx](#nginx-standalone) |
| 19 | + - [nginx kubernetes ingress](#nginx-ingress) |
| 20 | +- Traefik |
| 21 | + - [Standalone Traefik](#traefik-standalone) |
| 22 | + - [Traefik kubernetes ingress](#traefik-ingress) |
| 23 | +- [envoy](#envoy) |
| 24 | +- [No reverse proxy](#no-reverse-proxy) |
| 25 | + |
| 26 | +#### nginx Standalone |
| 27 | + |
| 28 | +Add this configuration snippet in your authentik virtual host: |
| 29 | + |
| 30 | +```nginx |
| 31 | +# server { |
| 32 | + ssl_client_certificate /etc/ssl/path-to-my-ca.pem; |
| 33 | + ssl_verify_client on; |
| 34 | +
|
| 35 | + # location / { |
| 36 | + proxy_set_header ssl-client-cert $ssl_client_escaped_cert; |
| 37 | + # } |
| 38 | +# } |
| 39 | +``` |
| 40 | + |
| 41 | +See [nginx documentation](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate) for reference. |
| 42 | + |
| 43 | +#### nginx Ingress |
| 44 | + |
| 45 | +Add these annotations to your authentik ingress object: |
| 46 | + |
| 47 | +```yaml |
| 48 | +nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true" |
| 49 | +# This secret needs to contain `ca.crt` which is the certificate authority to validate against. |
| 50 | +nginx.ingress.kubernetes.io/auth-tls-secret: namespace/secretName |
| 51 | +``` |
| 52 | +
|
| 53 | +See [ingress-nginx documentation](https://kubernetes.github.io/ingress-nginx/examples/auth/client-certs/) for reference. |
| 54 | +
|
| 55 | +#### Traefik Standalone |
| 56 | +
|
| 57 | +Add this snippet to your traefik configuration: |
| 58 | +
|
| 59 | +```yaml |
| 60 | +tls: |
| 61 | + options: |
| 62 | + default: |
| 63 | + clientAuth: |
| 64 | + # in PEM format. each file can contain multiple CAs. |
| 65 | + caFiles: |
| 66 | + - tests/clientca1.crt |
| 67 | + - tests/clientca2.crt |
| 68 | + clientAuthType: RequireAndVerifyClientCert |
| 69 | +``` |
| 70 | +
|
| 71 | +See the [Traefik mTLS documentation](https://doc.traefik.io/traefik/https/tls/#client-authentication-mtls) for reference. |
| 72 | +
|
| 73 | +#### Traefik Ingress |
| 74 | +
|
| 75 | +Create a middleware object with these options: |
| 76 | +
|
| 77 | +```yaml |
| 78 | +apiVersion: traefik.io/v1alpha1 |
| 79 | +kind: Middleware |
| 80 | +metadata: |
| 81 | + name: test-passtlsclientcert |
| 82 | +spec: |
| 83 | + passTLSClientCert: |
| 84 | + pem: true |
| 85 | +``` |
| 86 | +
|
| 87 | +See the [Traefik PassTLSClientCert documentation](https://doc.traefik.io/traefik/middlewares/http/passtlsclientcert/) for reference. |
| 88 | +
|
| 89 | +#### Envoy |
| 90 | +
|
| 91 | +See the [Envoy mTLS documentation](https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/securing#use-mutual-tls-mtls-to-enforce-client-certificate-authentication) and [Envoy header documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert) for configuration. |
| 92 | +
|
| 93 | +#### No reverse proxy |
| 94 | +
|
| 95 | +When using authentik without a reverse proxy, select the certificate authorities in the corresponding [brand](../../../../sys-mgmt/brands.md#client-certificates) for the domain, under **Other global settings**. |
| 96 | +
|
| 97 | +## Stage configuration |
| 98 | +
|
| 99 | +1. Log in as an admin to authentik, and go to the Admin interface. |
| 100 | +
|
| 101 | +2. In the Admin interface, navigate to **System -> Certificates** |
| 102 | +
|
| 103 | +3. Create a new certificate for the Certificate Authority used to sign client certificates. |
| 104 | +
|
| 105 | +4. In the Admin interface, navigate to **Flows -> Stages**. |
| 106 | +
|
| 107 | +5. Click **Create**, and select **Mutual TLS Stage**, and in the **New stage** box, define the following fields: |
| 108 | +
|
| 109 | + - **Name**: define a descriptive name, such as "chrome-device-trust". |
| 110 | +
|
| 111 | + - **Stage-specific settings** |
| 112 | +
|
| 113 | + - **Mode**: Configure the mode this stage operates in. |
| 114 | +
|
| 115 | + - **Certificate optional**: When no certificate is provided by the user or the reverse proxy, the flow will continue to the next stage. |
| 116 | + - **Certificate required**: When no certificate is provided, the flow ends with an error message. |
| 117 | +
|
| 118 | + - **Certificate authorities**: Select the certificate authorities used to sign client certificates. |
| 119 | +
|
| 120 | + - **Certificate attribute**: Select the attribute of the certificate to be used to find a user for authentication. |
| 121 | +
|
| 122 | + - **User attribute**: Select the attribute of the user the certificate should be compared against. |
| 123 | +
|
| 124 | +6. Click **Finish**. |
0 commit comments