> ## Documentation Index
> Fetch the complete documentation index at: https://ngrok.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Managing TLS Termination for Secure Connections

> Configure TLS termination in Kubernetes to use custom certificates, enforce TLS versions, and enable mutual TLS.

When using Ingress and Gateway API resources with the ngrok Kubernetes Operator, HTTPS endpoints are created by default, and ngrok automatically terminates TLS for secure traffic handling.

By customizing TLS termination settings, you can:

🔐 Use your own TLS certificates instead of ngrok-managed certificates. <br />
⚡ Enforce specific TLS versions for enhanced security. <br />
🔄 Configure mutual TLS (mTLS) for bidirectional authentication between clients and your services. <br />

## 🔍 What are the benefits of customizing TLS termination?

TLS termination is essential for securing data in transit. Customizing TLS settings allows you to:

* Control certificate management, choosing between automatically provisioned or manually managed TLS certificates.
* Enforce strong encryption standards by restricting which TLS versions are accepted.
* Enable mutual TLS (mTLS) for client authentication, adding an extra layer of security.

Key Benefits:

* **Enhance Security:** Enforce TLS policies that comply with industry best practices.
* **Use Custom Certificates:** Deploy your own TLS certificates to meet security or compliance requirements.
* **Improve Client Authentication:** Implement mutual TLS (mTLS) to verify both server and client identities.
* **Ensure Compatibility:** Control TLS versions for secure connections.
* **Meet Compliance Standards:** Enforce safety and security policies for HIPAA, PCI DSS, SOC 2, and other security frameworks.
* **Multi-tenant Environments:** Serve different certificates per domain in multi-tenant environments.

## TLS termination examples

The following examples showcase how you can create an endpoint that:

* Terminates TLS using a custom certificate
* Enforces mutual TLS with the clients
* Allows a max TLS version of 1.3
* Requires a minimum TLS version of 1.3

### 1. Generate certificates

```bash theme={null}
# 1. Generate CA private key (ca.key)
openssl genpkey -algorithm RSA -out ca.key -pkeyopt rsa_keygen_bits:2048

# 2. Generate CA certificate (ca.crt)
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt -subj "/CN=ExampleCA"

# 3. Generate server private key (server.key)
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048

# 4. Generate server certificate signing request (CSR) (server.csr)
openssl req -new -key server.key -out server.csr -subj "/CN=terminate-tls-example.ngrok.app"

# 5. Generate server certificate (server.crt)
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256

# 6. Generate client private key (client.key)
openssl genpkey -algorithm RSA -out client.key -pkeyopt rsa_keygen_bits:2048

# 7. Generate client certificate signing request (CSR) (client.csr)
openssl req -new -key client.key -out client.csr -subj "/CN=ExampleClient"

# 8. Generate client certificate (client.crt) with Client Authentication
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256 -extfile <(printf "extendedKeyUsage = clientAuth")
```

These commands will generate the following files:

* CA Files:
  * `ca.key`: CA private key
  * `ca.crt`: CA certificate
* Server Files:
  * `server.key`: Server private key
  * `server.csr`: Server certificate signing request
  * `server.crt`: Server certificate
* Client Files:
* `client.key`: Client private key
* `client.csr`: Client certificate signing request
* `client.crt`: Client certificate (with proper clientAuth extension for mTLS)

### 2. Create an endpoint with custom TLS termination

<Tabs>
  <Tab title="AgentEndpoint">
    Check out the [terminate TLS Traffic Policy action](/traffic-policy/actions/terminate-tls/) page for more details about how it functions and the parameters it accepts.

    ```yaml theme={null}
    apiVersion: ngrok.k8s.ngrok.com/v1alpha1
    kind: AgentEndpoint
    metadata:
      name: example-agent-endpoint
    spec:
      url: https://example-hostname.ngrok.io
      upstream:
        url: http://my-service.my-namespace:8080
      trafficPolicy:
        inline:
          on_tcp_connect:
            - actions:
                - type: terminate-tls
                  config:
                    min_version: "1.3"
                    max_version: "1.3"
                    server_private_key: |-
                      -----BEGIN PRIVATE KEY-----
                      ... private key ...
                      -----END PRIVATE KEY-----
                    server_certificate: |-
                      -----BEGIN CERTIFICATE-----
                      ... certificate ...
                      -----END CERTIFICATE-----
                    mutual_tls_certificate_authorities:
                      - |-
                        -----BEGIN CERTIFICATE-----
                        ... certificate ...
                        -----END CERTIFICATE-----
    ```
  </Tab>

  <Tab title="CloudEndpoint">
    Check out the [terminate TLS Traffic Policy action](/traffic-policy/actions/terminate-tls/) page for more details about how it functions and the parameters it accepts.

    ```yaml theme={null}
    apiVersion: ngrok.k8s.ngrok.com/v1alpha1
    kind: CloudEndpoint
    metadata:
      name: example-cloud-endpoint
    spec:
      url: https://example-hostname.ngrok.io
      trafficPolicy:
        policy:
          on_tcp_connect:
            - actions:
                - type: terminate-tls
                  config:
                    min_version: "1.3"
                    max_version: "1.3"
                    server_private_key: |-
                      -----BEGIN PRIVATE KEY-----
                      ... private key ...
                      -----END PRIVATE KEY-----
                    server_certificate: |-
                      -----BEGIN CERTIFICATE-----
                      ... certificate ...
                      -----END CERTIFICATE-----
                    mutual_tls_certificate_authorities:
                      - |-
                        -----BEGIN CERTIFICATE-----
                        ... certificate ...
                        -----END CERTIFICATE-----
    ```
  </Tab>

  <Tab title="Ingress">
    💡 `Ingress` resources do not natively support advanced TLS termination options, but they can be extended using a Traffic Policy.

    Check out the [terminate TLS Traffic Policy action](/traffic-policy/actions/terminate-tls/) page for more details about how it functions and the parameters it accepts.

    ### 3. Create an `NgrokTrafficPolicy`

    ```yaml theme={null}
    apiVersion: ngrok.k8s.ngrok.com/v1alpha1
    kind: NgrokTrafficPolicy
    metadata:
      name: example-tp
      namespace: default
    spec:
      policy:
        on_tcp_connect:
          - actions:
              - type: terminate-tls
                config:
                  min_version: "1.3"
                  max_version: "1.3"
                  server_private_key: |-
                    -----BEGIN PRIVATE KEY-----
                    ... private key ...
                    -----END PRIVATE KEY-----
                  server_certificate: |-
                    -----BEGIN CERTIFICATE-----
                    ... certificate ...
                    -----END CERTIFICATE-----
                  mutual_tls_certificate_authorities:
                    - |-
                      -----BEGIN CERTIFICATE-----
                      ... certificate ...
                      -----END CERTIFICATE-----
    ```

    ### 4. Use the `NgrokTrafficPolicy` on an `Ingress`

    ```yaml theme={null}
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        k8s.ngrok.com/traffic-policy: example-tp
      name: example-ingress
      namespace: default
    spec:
      ingressClassName: ngrok
      rules:
        - host: example-hostname.ngrok.io
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: example-service
                    port:
                      number: 80
    ```
  </Tab>

  <Tab title="Gateway API">
    ✅ Gateway API natively supports TLS termination, and this feature is fully supported by the ngrok Kubernetes Operator.

    ### 3. Create a `Secret` to terminate TLS

    Create a Kubernetes `Secret` to configure TLS termination.

    ```bash theme={null}
    kubectl create secret tls server-cert-secret \
    --cert=server.crt \
    --key=server.key
    ```

    ### 4. Create a `ConfigMap` to validate client certificates

    Create a Kubernetes `ConfigMap` containing the CA so that client certificates can be validated.

    ```bash theme={null}
    kubectl create configmap ca-cert-config \
    --from-file=ca.crt
    ```

    ### 5. Create a `Gateway` that terminates TLS using the generated certificates

    ```yaml theme={null}
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: example-gateway
      namespace: default
    spec:
      gatewayClassName: ngrok
      listeners:
        - name: example
          hostname: "example-hostname.ngrok.io"
          port: 443
          protocol: HTTPS
          tls:
            mode: Terminate
            certificateRefs:
            - kind: Secret
              name: server-cert-secret
            frontendValidation:
              caCertificateRefs:
              - kind: ConfigMap
                name: ca-cert-config
            options:
              "k8s.ngrok.com/terminate-tls.min_version": "1.2"
              "k8s.ngrok.com/terminate-tls.max_version": "1.3"
              "k8s.ngrok.com/terminate-tls.mutual_tls_verification_strategy": "require-and-verify"
    ```

    ### 6. Generate an `HTTPRoute` to route to the upstream

    ```yaml theme={null}
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: example-route
      namespace: default
    spec:
      hostnames:
      - example-hostname.ngrok.io
      parentRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: example-gateway
        namespace: default
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /
        backendRefs:
          - group: ""
            kind: Service
            name: example-service
            port: 80
            weight: 1
    ```
  </Tab>
</Tabs>

### Use the client certificates while making requests

Now that mutual TLS is enforced, you will need to include the client certificate when making requests

```bash theme={null}
curl --cert client.crt --key client.key --cacert ca.crt https://<your hostname>
```
