# TLS Settings

This reference covers all of Pomerium's TLS route settings:

- [TLS Client Certificate](#tls-client-certificate)
- [TLS Custom Certificate Authority](#tls-custom-certificate-authority)
- [TLS Downstream Client Certificate Authority](#tls-downstream-client-certificate-authority)
- [TLS Downstream Server Name](#tls-downstream-server-name)
- [TLS Server Name](#tls-server-name)
- [TLS Skip Verification](#tls-skip-verification)
- [TLS Upstream Allow Renegotiation](#tls-upstream-allow-renegotiation)
- [TLS Upstream Server Name](#tls-upstream-server-name)

## TLS Client Certificate

If specified, Pomerium will present this client certificate to upstream services when requested to enforce [mutual authentication](https://en.wikipedia.org/wiki/Mutual_authentication) (mTLS).

For more details, see our [mTLS example repository](https://github.com/pomerium/pomerium/tree/main/examples/mutual-tls) and the [Upstream mTLS With Pomerium](https://www.pomerium.com/docs/internals/certificates-and-tls.md) guide.

### How to configure

**Core:**

| **YAML**/**JSON** setting | **Type** | **Usage** |
| :-- | :-- | :-- |
| `tls_client_cert` and `tls_client_key` | `string` (base64-encoded) | **optional** |
| `tls_client_cert_file` and `tls_client_key_file` | `string` (file path) | **optional** |

### Examples

```yaml
tls_client_cert: base64-encoded-certificate
tls_client_key: base64-encoded-keywords

# or
tls_client_cert_file: /relative/file/location
tls_client_key_file: /relative/file/location
```

**Enterprise:**

**Kubernetes:**

See Kubernetes [TLS Certificates](https://www.pomerium.com/docs/deploy/k8s/ingress.md#tls-certificates) for more information

## TLS Custom Certificate Authority

**TLS Custom Certificate Authority** defines a set of root certificate authorities that the Pomerium Proxy Service uses when verifying upstream server certificates.

**Note**: This setting will replace (not append) the system's trust store for a given route.

### How to configure

**Core:**

| **YAML**/**JSON** setting               | **Type** | **Usage**    |
| :-------------------------------------- | :------- | :----------- |
| `tls_custom_ca` or `tls_custom_ca_file` | `string` | **optional** |

### Examples

```yaml
tls_custom_ca: base64-encoded-custom-ca
tls_custom_ca_file: /relative/file/location
```

**Enterprise:**

**Kubernetes:**

See Kubernetes [TLS Certificates](https://www.pomerium.com/docs/deploy/k8s/ingress.md#tls-certificates) for more information

## TLS Downstream Client Certificate Authority

This setting is deprecated, and will be removed in a future release.

If you previously used this setting to require client certificates only on certain routes, you can achieve this same behavior by setting the new downstream mTLS [**Enforcement Mode**](https://www.pomerium.com/docs/reference/downstream-mtls-settings.md#enforcement-mode) option to the value `policy` and adding a policy deny rule with the `invalid_client_certificate` criterion on all routes that should require client certificates.

If you want to enforce an allowlist or denylist of specific certificates on a particular route, you can use the new [`client_certificate`](https://www.pomerium.com/docs/internals/ppl.md#certificate-matcher) policy criterion.

If you do need to set completely different trusted client CAs for different routes, we recommend running separate Pomerium clusters for each set of trusted client CAs.

If specified, downstream clients (like a user's browser) will be required to provide a valid client TLS certificate. This overrides the global `downstream_mtls.ca` option for this route.

See [Client-Side mTLS With Pomerium](https://www.pomerium.com/docs/internals/mutual-auth.md) for more information.

### How to configure

**Core:**

| **YAML**/**JSON** setting | **Type** | **Usage** |
| :-- | :-- | :-- |
| `tls_downstream_client_ca` or `tls_downstream_client_ca_file` | `string` | **optional** |

### Examples

```yaml
tls_downstream_client_ca: base64-encoded-client-ca
tls_downstream_client_ca_file: /relative/file/location
```

**Enterprise:**

**Kubernetes:**

See Kubernetes [TLS Certificates](https://www.pomerium.com/docs/deploy/k8s/ingress.md#tls-certificates) for more information

## TLS Downstream Server Name

**TLS Downstream Server Name** overrides the hostname specified in the `from` field. When a connection to Pomerium is made via TLS the `tls_downstream_server_name` will be used as the expected Server Name Indication, whereas the host part of the `from` field, will be expected to match the `Host` or `:authority` headers of the HTTP request.

### How to configure

**Core:**

| **YAML**/**JSON** setting    | **Type** | **Usage**    |
| :--------------------------- | :------- | :----------- |
| `tls_downstream_server_name` | `string` | **optional** |

**Enterprise:**

**Kubernetes:**

Kubernetes does not support `tls_downstream_server_name`

## TLS Server Name

**TLS Server Name** overrides the hostname specified in the `to` field for TLS certificate verification and SNI. This is useful when your backend is an HTTPS server with a valid certificate, but you want to communicate with it using an internal hostname (for example, a Docker container name).

If [`tls_upstream_server_name`](#tls-upstream-server-name) is also set, it takes precedence over this setting.

### How to configure

**Core:**

| **YAML**/**JSON** setting | **Type** | **Usage**    |
| :------------------------ | :------- | :----------- |
| `tls_server_name`         | `string` | **optional** |

### Examples

```yaml
tls_server_name: backend.internal.example.com
```

**Enterprise:**

Configure **TLS Server Name** in the Console under the route TLS settings.

**Kubernetes:**

| **[Annotation name](https://www.pomerium.com/docs/deploy/k8s/ingress.md#set-ingress-annotations)** | **Type** | **Usage** |
| :-- | :-- | :-- |
| `tls_server_name` | `string` | **optional** |

### Examples

```yaml
ingress.pomerium.io/tls_server_name: 'backend.internal.example.com'
```

## TLS Skip Verification

TLS Skip Verification controls whether the Pomerium Proxy Service verifies the upstream server's certificate chain and host name.

If enabled, Pomerium accepts any certificate presented by the upstream server and any host name in that certificate.

In this mode, TLS is susceptible to man-in-the-middle attacks. This should be used only for testing.

### How to configure

**Core:**

| **YAML**/**JSON** setting | **Type**  | **Default** |
| :------------------------ | :-------- | :---------- |
| `tls_skip_verify`         | `boolean` | `false`     |

### Examples

```yaml
tls_skip_verify: true
```

**Enterprise:**

**Kubernetes:**

| **[Annotation name](https://www.pomerium.com/docs/deploy/k8s/ingress.md#set-ingress-annotations)** | **Type** | **Default** |
| :-- | :-- | :-- |
| `tls_skip_verify` | `boolean` | `false` |

### Examples

```yaml
ingress.pomerium.io/tls_skip_verify: 'true'
```

## TLS Upstream Allow Renegotiation

**TLS Upstream Allow Renegotiation** controls whether server-initiated TLS renegotiation is allowed for upstream servers. For more details, see Envoy's documentation on [`allow_renegotiation`](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/tls.proto).

TLS renegotiation is considered insecure and shouldn't be used unless absolutely necessary.

### How to configure

**Core:**

| **YAML**/**JSON** setting          | **Type**  | **Default** |
| :--------------------------------- | :-------- | :---------- |
| `tls_upstream_allow_renegotiation` | `boolean` | `false`     |

### Examples

```yaml
tls_upstream_allow_renegotiation: true
```

**Enterprise:**

**Kubernetes:**

Kubernetes does not support **TLS Upstream Allow Renegotiation**

## TLS Upstream Server Name

**TLS Upstream Server Name** overrides the hostname specified in the `to` field for TLS certificate verification and SNI. If set, this server name will be used to verify the certificate name. This is useful when the backend of your service is a TLS server with a valid certificate, but mismatched name.

This setting takes precedence over [`tls_server_name`](#tls-server-name) if both are set.

### How to configure

**Core:**

| **YAML**/**JSON** setting  | **Type** | **Usage**    |
| :------------------------- | :------- | :----------- |
| `tls_upstream_server_name` | `string` | **optional** |

**Enterprise:**

**Kubernetes:**

Kubernetes does not support `tls_upstream_server_name`
