Skip to content

How It Works

Minh Tu Le edited this page Nov 9, 2025 · 3 revisions

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.

Kubernetes Authentication, Authorization and Audit

Authentication

The Gateway first authenticates the user using the Gateway Access Token (GAT). This token is issued by the Twingate control plane after the user satisfies all security policies of the Kubernetes resource—the same policies that apply to network resources in Twingate, including MFA, device trust, geo-location, and conditional access policies like JIT. The Twingate Client includes the GAT in its initial request to authenticate to the Gateway.

The Gateway then authenticates to the protected Kubernetes API server using a service account token, and impersonates the Twingate user using Kubernetes impersonation headers. The service account must have necessary impersonation permissions.

  • In-cluster: When the Gateway is deployed inside the cluster, it uses the token of the service account associated with the Gateway pod. The Gateway Helm chart will create a dedicated service account for the Gateway with necessary impersonation permissions.
  • Out-cluster: When the Gateway is deployed outside the cluster, it must be configured with a service account token that has necessary impersonation permissions.

Authorization

Kubernetes RBAC authorization can be configured based on Twingate identity forwarded by the Gateway via impersonation headers.

The Gateway forwards both Twingate user email and their groups to the Kubernetes API server. Only groups that grant the user access to the Kubernetes resource are forwarded.

$ kubectl --context twingate-k8s-cluster auth whoami
ATTRIBUTE   VALUE
Username    [email protected]
Groups      [engineering on-call twingate:authenticated system:authenticated]

For Twingate service accounts, the Gateway forwards the service account key ID as the username and the service account name and ID as groups to the Kubernetes API server.

$ kubectl --context twingate-k8s-cluster auth whoami
ATTRIBUTE   VALUE
Username    <service-account-key-id>
Groups      [<service-account-name> <service-account-id> twingate:service-accounts twingate:authenticated system:authenticated]

Special groups:

  • twingate:authenticated: All entities authenticated by Twingate
  • twingate:service-accounts: All service accounts authenticated by Twingate

Audit

The Gateway logs all HTTP requests and interactive sessions, e.g. kubectl exec, to standard output, which can be configured to forward to a storage system. See Session Recordings for more details.

Clone this wiki locally