blog
Why kubelatch exists
Most teams first reach their Kubernetes clusters the same way: with one admin kubeconfig, shared. Nobody decides that as a policy. It's what the cluster gives you on day one, and it works. kubelatch exists because that file has a cost that grows quietly, and because the alternative can be small.
The file everyone has
When you create a cluster, you get a kubeconfig that can do everything. Someone puts it somewhere safe, often a password vault. Then the first colleague needs to look at a pod, and the file goes to a laptop. Someone else joins, and it goes to another one. A deploy pipeline has to reach the cluster, so a copy is pasted into the CI system's secrets. A few months later there are more copies than anyone could list.
None of this is careless. Each step makes sense on the day it happens: the team is small, everyone is trusted, and the work has to get done. The file isn't the villain here. It's a credential made for setting a cluster up, and it ends up being the way everyone works on it.
What it costs
The cost doesn't show while things go well. It shows the day you need to answer a question.
Who has it? Nobody knows for sure. Copies live on laptops, in CI settings, in old chat threads. There's no list.
Who did that? The cluster's audit log says kubernetes-admin, or whatever name the file carries. It's the same name for every person and every pipeline, so the log tells you that something happened, not who did it.
Can we take it back? Not quickly. An admin kubeconfig usually carries a client certificate, and Kubernetes doesn't revoke certificates: one that's been issued stays valid until it expires, often a year or more. Taking the file back means rotating credentials on the whole cluster and handing out a new file. That's a project, and projects get postponed.
Someone leaves. Even on the best of terms, their laptop had a copy. The only way to be sure it no longer works is that same rotation, on every cluster the file reached. It's easy to put off, and the copy stays valid in the meantime.
The other thing
What I wanted instead is simple to say: one credential per person, per pipeline and per agent, each with an owner and an end date, and a cluster that sees who is really calling.
That's what kubelatch does. It sits in front of your clusters' API servers as a proxy, and every credential belongs to someone. A person gets a klt_ token and its kubeconfig, which expires on its own: 30 days at most, by default. A GitHub Actions job exchanges the OIDC token GitHub gives it for a one-hour credential, with no secret stored in the repository. An AI agent works through kubelatch's MCP server, either as a bot an administrator sets up or on your behalf, with your permissions cut down and for a few hours.
When a request arrives, kubelatch checks the token, records the request and forwards it to the cluster impersonating whoever made it. The API server no longer sees a shared admin: it sees user:ana, with the groups from Ana's active permissions. The cluster still decides every verb with its own RBAC; kubelatch only tells it who is asking. Why a proxy explains this design and what it costs.
That answers the questions from before. The inventory says who each credential belongs to, which clusters it reaches, until when it's valid and when it was last used. Revoking one takes effect on the next request, which gets a 401. And with the GitHub App configured, someone who leaves your GitHub organization is disabled on their own: their credentials are revoked and any agent acting for them is cut. Nothing to rotate. Identity explains how.
What kubelatch is not
- Not a single sign-on. It has no identity provider of its own: people sign in with GitHub, through a GitHub App of your organization, or with local accounts.
- Not a service mesh. It isn't in the path of your workloads, and your applications don't depend on it.
- Not a bastion for everything. It guards one door, the Kubernetes API, and records what goes through it. It doesn't record sessions or relay into private networks.
It's also small on purpose: one Go binary and Postgres. The web interface, the API, the proxy and the RBAC reconciler run in the same process, and all state lives in the database. On each cluster it needs two ServiceAccounts and the standard Kubernetes API: no API server flags, nothing on the nodes, no agent per cluster. That's why it works the same on EKS, GKE and AKS as on kubeadm, k3s, RKE2 or Talos.
Now the limit. kubelatch is in the path of every request people and CI make. If it goes down, they lose access through it, although your workloads keep running. So kubelatch must never be the only way into a cluster: you keep native emergency access to each one, such as your cloud's administrator identity or, on a self-managed cluster, the admin kubeconfig in a vault with audited access, and you test it. What goes through that door is recorded in the cluster's own audit log, not in kubelatch's. The file from the start of this post doesn't disappear. It goes back to the vault, for the day you need it.
Try it
The quickest way to see all this is the local tutorial. On your own machine, with a disposable kind cluster and local passwords, you grant yourself a permission, use kubectl through kubelatch, find each request in the audit log, and revoke the credential: the next kubectl gets a 401. It takes about fifteen minutes, plus the first downloads.
kubelatch is free for 2 clusters and 5 people, with no sign-up and no time limit; bots, pipelines and agents don't count as people. Pricing has the rest. kubelatch is made by one person, in Spain: if something here doesn't match what you see when you try it, write to me.