Skip to content

How It Works

Minh Tu Le edited this page Nov 3, 2025 · 1 revision

The Kubernetes Access Gateway acts as an authenticated L7 proxy between kubectl and your Kubernetes API server, enabling secure access to private clusters through Twingate's Zero Trust network.

Connection Flow

A Kubernetes resource is configured on Twingate as follows:

  • Address: 10.0.0.1 - The address of the Kubernetes API server that is reachable by the Gateway
  • Gateway Address: gateway.int - The address of the Gateway that is reachable by the Connector
  • Certificate Authority certificate: the CA certificate to verify the TLS certificate served by the Gateway

The diagram below shows how a kubectl command reaches a private Kubernetes cluster:

sequenceDiagram
    autonumber
    participant kubectl
    participant Client as Twingate Client

    box Private Network
        participant Connector as Twingate Connector
        participant Gateway as Kubernetes Access Gateway<br/>(gateway.int)
        participant K8s as Kubernetes API Server<br/>(10.0.0.1)
    end

    Note over kubectl: ~/.kube/config configured by Twingate Client<br/>with API server address (10.0.0.1) and CA certificate

    Note over kubectl: kubectl get pods

    kubectl->>Client: TCP to 10.0.0.1

    Note over Client,Connector: 🔒 Encrypted Tunnel

    Connector->>Gateway: Forward TCP connection

    Note over Client,Gateway: 🔒 TLS handshake (outer layer)

    Client->>Gateway: HTTP CONNECT with GAT token

    Gateway->>Gateway: Validate GAT token

    Gateway-->>Client: 200 Connection Established

    Note over kubectl,Gateway: 🔒 TLS handshake (inner layer)

    kubectl->>Gateway: HTTP request (GET /api/v1/namespaces/default/pods)
    Gateway->>K8s: Forward HTTP request
    K8s-->>Gateway: HTTP response
    Gateway-->>kubectl: Forward response
Loading

Connection Steps

  • kubeconfig Sync: The Twingate Client automatically updates ~/.kube/config with the Kubernetes resource configuration, allowing the user to switch to the kubecontext and run kubectl commands seamlessly.
  • 1️⃣ kubectl Initiates Connection: The user runs kubectl get pods, which opens a TCP connection to 10.0.0.1. Traffic flows through Twingate's encrypted tunnel between Client and Connector.
  • 2️⃣ Connector Routes to Gateway: The Connector recognizes this as a Kubernetes resource and forwards the connection to gateway.int instead of the resource address.
  • Outer TLS: Client establishes TLS with the Gateway for the HTTP CONNECT tunnel.
  • 3️⃣ 4️⃣ 5️⃣ Authentication: Client sends HTTP CONNECT request with the GAT token; Gateway validates it.
  • Inner TLS: kubectl establishes its own TLS connection with the Gateway (thinking it's talking to the API server).
  • 6️⃣ 7️⃣ 8️⃣ 9️⃣ Request Proxying: Gateway forwards the HTTP request to the Kubernetes API server at 10.0.0.1, and returns the response to kubectl.

Resource Address

Like Network resources in Twingate, a Kubernetes resource's address should point to the final destination—the Kubernetes API server that the Gateway can reach.

Multiple Clusters with the Same Address

When the Gateway is deployed inside the cluster, multiple Kubernetes resources may share the same address (e.g., kubernetes.default.svc.cluster.local). To distinguish between them, use resource aliases:

  • Resource A
    • Address: kubernetes.default.svc.cluster.local
    • Alias: cluster-a.int
  • Resource B
    • Address: kubernetes.default.svc.cluster.local
    • Alias: cluster-b.int

Twingate Client uses the resource aliases instead of the addresses when syncing kubeconfig. Each resource gets a unique kubecontext in ~/.kube/config, allowing users to switch between clusters even when they share the same underlying address.

TLS Certificates

The Gateway terminates two TLS connections, presenting itself as the Kubernetes API server:

  • Outer TLS: Twingate Client connects to the resource address (e.g., 10.0.0.1) and validates the certificate against this hostname
  • Inner TLS: kubectl connects using the hostname from kubeconfig (e.g., the resource address, 10.0.0.1, or the resource alias, cluster-a.int) and validates the certificate against this hostname

The Gateway's TLS certificate must include all possible hostnames in the Subject Alternative Name (SAN) field:

  • All resource addresses (e.g., 10.0.0.1, kubernetes.default.svc.cluster.local)
  • All resource aliases, if configured (e.g., cluster-a.int, cluster-b.int)

This ensures both the Twingate Client and kubectl can successfully validate the certificate during their respective TLS handshakes.

Clone this wiki locally