Skip to content

kubelatch on top of the SSO you already have

Many clusters already have their own sign-in: EKS with IAM or an OIDC provider, AKS with Entra ID, GKE with Google accounts, a k3s or kubeadm cluster with --oidc-* flags. Their RBAC is already written against those users and groups. This page explains how kubelatch fits on top of that sign-in instead of beside it, and what it still does its own way.

Two worlds side by side

By default, kubelatch sends the cluster names of its own. A person enters as user:<login>, and each permission is a group such as kubelatch:ns:apps:developer, bound by a binding kubelatch writes. Inside the cluster that is a world of its own: the apiserver's audit log names Ana twice (oidc:ana@acme.com when she uses the cluster's SSO, user:ana when she comes through kubelatch), and the team keeps two sets of bindings for the same people.

OIDC login already lets people sign in to kubelatch with the same identity provider. Two more pieces carry that identity into the cluster.

What changes

  • Native roles. A native role names one or more groups the cluster already knows, such as oidc:developers. A permission of that role is temporary membership in those groups: the proxy sends them as Impersonate-Group while the permission lasts, and the bindings the cluster already has for them apply. kubelatch writes no binding for a native role. Expiry, revocation, approvals and the audit work as for any other role.
  • The cluster's own identity. Each cluster has an identity template that says how kubelatch names people there, such as oidc:{email}. With it, Ana enters that cluster as oidc:ana@acme.com whichever way she comes in, so the apiserver's audit log and the bindings to users name her the same. The default, user:{login}, keeps today's names.

Neither needs a change in your RBAC or a new bootstrap manifest: kubelatch only reads the bindings the cluster has, with the rights it already had. Native roles need the current bootstrap (v2), as custom roles do.

What stays the same

  • kubelatch still enters the cluster with its own ServiceAccount and acts for each person by impersonation. The cluster's SSO does not see the person's kubelatch credential, and kubelatch does not see the person's SSO tokens.
  • The proxy can impersonate a name only while a permission that gives it is active: each native group and each name the template renders is in the impersonation list of the cluster only then, and leaves it on the next pass. When a permission expires, the proxy stops sending its groups at once.
  • Impersonate-Uid still carries the account's own identifier, so the apiserver's audit log tells two people apart even if their names change or clash.
  • Bots always enter as bot:<name>.

The name carries everything the cluster binds to it

Until now the RBAC that applied to a request through kubelatch was exactly the RBAC kubelatch wrote, because only kubelatch used its names. A native group or a rendered user name changes that: the cluster applies every binding it holds for that name, whoever wrote it. If the cluster binds oidc:platform-admins to cluster-admin, a native role with that group gives cluster-admin; if it binds oidc:ana@acme.com to cluster-admin, any permission of Ana's on that cluster does, even a one-hour viewer.

kubelatch doesn't forbid that, because it is the usual way managed clusters give administrators their access. It bounds it like the cluster-admin role:

  • A permission that would make someone cluster-admin through a ClusterRoleBinding of the cluster needs an expiry of 8 hours at most. kubelatch reads the cluster's ClusterRoleBindings at the moment of granting, never from a cache, and refuses the permission if it can't read them.
  • A native role whose group is bound to cluster-admin can't be a group permission: future members would inherit it with no check.
  • Every reconciliation reads the bindings again. A group or a user bound to cluster-admin that some active permission gives without that expiry stays out of the impersonation list, and the cluster goes to Error saying who and why. This covers a binding added after the grant.
  • AI agents never receive a native role, and always enter a cluster as the person's kubelatch name, user:<login>, never as the cluster's name for the person (AI agents).

What kubelatch reads is RBAC: ClusterRoleBindings whose role is the ClusterRole cluster-admin. It can't see a ClusterRole of another name that grants as much, nor what an authorizer outside RBAC grants, such as cloud IAM roles on GKE, Azure RBAC on AKS or access policies on EKS. Pick the groups of a native role, and the template of a cluster, knowing what the cluster gives those names; Cluster SSO by provider shows how each provider names them.

When to use each

You want Use
Permissions that kubelatch writes and can show you rule by rule A system role or a custom role
Temporary access to what a group of the cluster's SSO already has A native role
The cluster's audit log and bindings to users to name people as its SSO does The cluster's identity template

They mix: a cluster with the template oidc:{email} takes system, custom and native roles alike, and a native role works with the default template too.