Skip to main content
Exposing the Kubernetes API server through ngrok lets you reach your cluster’s control plane from anywhere—no VPN, no bastion host, no firewall rules required. Common use cases include:
  • Running kubectl commands remotely without VPN access
  • Enabling CI/CD pipelines outside the cluster to deploy resources
  • Giving teammates temporary access to a development cluster
  • Accessing clusters running in air-gapped or private networks
The ngrok Operator creates a persistent, secure tunnel from your cluster to ngrok’s global network. However, the type of ngrok endpoint you need depends on which Kubernetes authentication strategy your cluster uses, since some auth mechanisms rely on TLS client certificates that require end-to-end TLS passthrough.

Prerequisites

Kubernetes authentication strategies

As of Kubernetes 1.33, the following authentication strategies are available. From a kubectl client perspective they correspond to specific fields in your kubeconfig, which determines which ngrok endpoint type to use.
*Kubernetes can delegate authentication to a reverse proxy that sits in front of the API server. Since the proxy itself handles authentication—-not the API server or kubectl—-ngrok’s role is limited to transporting traffic. Whether this works depends on where the proxy sits in your architecture relative to the ngrok tunnel. This topology is outside the scope of this guide.

Why endpoint type matters

HTTPS endpoints terminate TLS on ngrok’s network. The Authorization: Bearer <token> header passes through transparently to the Kubernetes API server, so any token-based strategy works. TLS endpoints pass the raw TLS stream through to the upstream without ngrok terminating it. This means the full TLS handshake—including the client certificate—travels end-to-end from kubectl to the Kubernetes API server. This is required for X.509 client certificate authentication. If you use HTTPS with client certificate auth, ngrok will terminate TLS before the client cert reaches the API server and authentication will fail.

Identifying your authentication strategy

Open your kubeconfig (default location: ~/.kube/config) and find the users section for the relevant cluster.

Bearer token

Your kubeconfig has a token or tokenFile field directly under user:
or
→ Use the HTTPS endpoint setup.

Exec credential plugin

Your kubeconfig has an exec block under user. This is used by cloud providers (EKS, GKE, AKS) and OIDC login tools:
Most exec plugins (including all cloud provider implementations) produce a bearer token, not a client certificate. Check the plugin documentation to confirm. If the plugin returns a token: → Use the HTTPS endpoint setup. If the plugin returns clientCertificateData and clientKeyData: → Use the TLS passthrough setup.

X.509 client certificate

Your kubeconfig has client-certificate-data and client-key-data fields (or their file-based equivalents) under user:
or
→ Use the TLS passthrough setup.

Scenario 1: Bearer token or exec plugin producing a token (HTTPS)

Use this scenario when your kubeconfig uses token, tokenFile, or an exec block that produces a bearer token (the most common case for EKS, GKE, AKS, and OIDC).

Apply the AgentEndpoint manifest

Create an AgentEndpoint that exposes the in-cluster Kubernetes API service. Replace my-k8s-api.ngrok.app with your reserved ngrok domain.
Apply it:

Update your kubeconfig

Find the name of the cluster entry you want to update:
Replace the server with your ngrok endpoint(ex: https://my-k8s-api.ngrok.app)
Remove the previous certificate data as ngrok will now be terminating HTTPS for you:
Alternatively, edit ~/.kube/config directly. The cluster entry should look like:

Verify access

You should now be able to verify access by running any kubectl command.

Scenario 2: X.509 client certificate or exec plugin producing a certificate (TLS passthrough)

Use this scenario when your kubeconfig uses client-certificate-data / client-key-data fields or an exec plugin that outputs a client certificate. The tls:// endpoint type passes the raw TLS stream through ngrok without termination, so your client certificate reaches the Kubernetes API server directly.

Apply the AgentEndpoint manifest

Create an AgentEndpoint using the tls:// scheme for the public URL and tcp:// for the upstream. Replace my-k8s-api.ngrok.app with your desired domain.
Apply it:

Update your kubeconfig

With TLS passthrough, ngrok forwards the raw TLS handshake to the Kubernetes API server. The server still presents its original cluster certificate, so you keep certificate-authority-data pointing to the cluster CA.
Alternatively, edit ~/.kube/config directly. The cluster entry should look like:
The user section (with client-certificate-data and client-key-data) stays unchanged—these are passed through to the API server via the TLS handshake. Verify access:

Troubleshooting

If you get an error message like:
then the certificate presented by your Kubernetes API server is only valid for those server names and you will either need to:
  1. Create/Obtain a valid certificate and instruct your kubeapi server to use it. For example, you can use --apiserver-cert-extra-sans if using kubeadm OR
  2. Disable the TLS server verification step, as shown below, which comes with security implications that you should consider.
Alternatively, edit ~/.kube/config directly. The cluster entry should look like:

Security Recommendations

Exposing the Kubernetes API server publicly increases your attack surface. Apply these controls:

Restrict access by IP

Use a Traffic Policy on your AgentEndpoint to allow only known IP ranges. This prevents unauthorized clients from even reaching the API server.
See the restrict IPs guide for more details.

Kubernetes RBAC remains your primary authorization layer

ngrok handles transport security—the existing Kubernetes RBAC rules still control what any authenticated user can do. Ensure that service accounts and user accounts exposed through the ngrok endpoint follow the principle of least privilege.

Remove access when no longer needed

When remote access is no longer needed, delete the AgentEndpoint resource to immediately close the tunnel: