System roles¶
A kubelatch permission is always the combination of a subject, a cluster, a role and a scope. The six system roles, also called tiers, come with kubelatch: they can't be edited, and all but admin and cluster-admin can be duplicated into a custom role. Here you see what each tier allows, where it can be granted, what it requires and, above all, what it can't guarantee. Roles an administrator composes are in Roles.
The six system roles¶
| Tier | What it allows | Scope | Requires PSA |
|---|---|---|---|
viewer |
Read access to what Kubernetes' view role includes: pods, pods/log, workloads, services, configmaps… without secrets; plus the CPU and memory pods use (metrics.k8s.io, what kubectl top pods reads). With * scope, also read access to nodes and their usage, namespaces, persistentvolumes, storageclasses and CRDs. |
namespace or * |
No |
developer |
Everything in viewer plus creating, modifying and deleting deployments, statefulsets, daemonsets, replicasets, jobs, cronjobs, pods, configmaps, services, persistentvolumeclaims, ingresses and horizontalpodautoscalers, and scaling deployments, statefulsets and replicasets. |
namespace | Yes |
debugger |
Add-on: exec, attach and port-forward into pods, adding ephemeral containers, and reading pods and their logs. |
namespace | Yes |
secrets-reader |
Add-on: read access (get, list, watch) to secrets. |
namespace | No |
admin |
Kubernetes' admin role in the namespace. |
namespace | Yes |
cluster-admin |
Kubernetes' cluster-admin role across the whole cluster. Expiry required, 8 h maximum. |
* |
No |
A subject can have several permissions on the same cluster. It's common to combine them: developer on apps plus debugger on apps for someone who needs to get into their pods.
Which tier covers which¶
Some tiers include others whole. On the same cluster and scope, a permission with the one on the left makes a permission with the ones on the right redundant:
| Tier | Covers |
|---|---|
developer |
viewer |
admin |
developer, viewer |
cluster-admin |
admin, developer, viewer |
viewer, debugger, secrets-reader |
nothing |
debugger and secrets-reader are add-ons: nothing includes them and they include nothing. A custom role declares nothing either way. Every list of permissions uses this table to flag a redundant permission, for example viewer next to developer for the same account on the same namespace (Overlaps). Nothing is revoked on its own: a redundant permission gives nothing more, and it may outlast the one that covers it.
What developer leaves out, and why¶
developer is not Kubernetes' edit role. edit includes secrets, pods/exec and serviceaccounts/token, which are exactly what a day-to-day working permission shouldn't grant without thinking about it. developer does not have:
secrets,serviceaccountsorserviceaccounts/token;- the
exec,attach,portforward,proxyandephemeralcontainerssubresources of pods; roles,rolebindings,resourcequotasorlimitranges.
Those capabilities are split into separate tiers (debugger, secrets-reader, admin) so granting them is an explicit, audited decision.
The namespace is the boundary¶
Kubernetes says so in its own documentation: the boundaries within a namespace are weak. kubelatch can't change that, and it's worth understanding before granting anything.
Whoever can create pods in a namespace can mount any Secret in that namespace and use any ServiceAccount in that namespace, with its permissions. So:
- Whoever has
developeron a namespace reaches its Secrets and its ServiceAccounts, even though the tier doesn't includesecrets. All it takes is deploying a pod that mounts them. secrets-readeranddebuggerare conveniences, not boundaries. They save you from deploying a pod to read a Secret or to get a shell into another pod, but they don't protect anythingdeveloperdoesn't already reach.- ServiceAccount tokens obtained from a pod don't go through kubelatch. Whatever is done with them ends up in the cluster's native audit log, not kubelatch's. So it's worth keeping that native audit log active with the provider.
The practical consequence: grant developer, debugger and admin only on namespaces whose contents that person may see and touch. Whatever you want kept separate between teams, separate into different namespaces.
Pod Security Admission¶
Without Pod Security Admission, whoever can create pods can create a privileged one that mounts the node's disk, and from the node reaches the whole cluster. An ephemeral container added with debugger can do the same.
That's why developer, debugger and admin require the namespace to have the pod-security.kubernetes.io/enforce label set to baseline or restricted. kubelatch checks this when granting the permission, by reading the namespace on the cluster.
KUBELATCH_REQUIRE_PSA=false disables the check, and kubelatch warns about it at the top of Permissions and under Notices, the bell in the top bar. It only makes sense if another tool (OPA, Kyverno) enforces the same thing.
Protected namespaces¶
kube-system, kube-public, kube-node-lease and kubelatch-system don't accept permissions of any role, system or custom. KUBELATCH_PROTECTED_NAMESPACES adds others to the list. Whatever needs doing there is done with native admin access, outside kubelatch.
Allowed scopes¶
*(the whole cluster) is only allowed withviewerandcluster-admin.cluster-adminis only allowed with*.- All other tiers can only be granted on a namespace, which must exist on that cluster at the moment of granting.
- A custom role can be granted on a namespace, and with
*only if it can be granted to a whole cluster (Roles).
viewer with * also sees the logs of every namespace, and logs can contain secrets. Grant it knowing that.
cluster-admin as audited emergency access¶
cluster-admin gives full control of the cluster. kubelatch treats it as emergency access: it requires an expiry date and doesn't allow more than 8 h. Who granted it and to whom is recorded, and every request made with it ends up in the audit log. It's the preferred route for an urgent intervention while kubelatch is running.
How it's materialized on the cluster¶
The reconciler translates active permissions into standard RBAC on each cluster:
| Scope | Object it creates | Points to | Binding subject |
|---|---|---|---|
| Namespace | RoleBinding kubelatch-<tier> in that namespace |
ClusterRole for the tier | Group kubelatch:ns:<namespace>:<tier> |
* |
ClusterRoleBinding kubelatch-<tier>-cluster |
ClusterRole for the tier | Group kubelatch:cluster:<tier> |
Bindings never name people: they name groups. The proxy uses impersonation to act as each person with the groups from their active permissions, and the API server applies the bindings for those groups (see The journey of a request).
viewer, developer, debugger and secrets-reader are their own aggregated ClusterRoles (kubelatch-<tier>): their rules come from a base ClusterRole (kubelatch-<tier>-base) and from any other ClusterRole with the label kubelatch.io/aggregate-to-<tier>: "true". viewer also collects everything labeled for the standard view role, and developer collects everything from viewer. admin and cluster-admin point directly to the Kubernetes roles of the same name.
To extend a tier with a CRD, create a small ClusterRole with that label on the cluster; kubelatch picks it up without any change on its side.
A binding exists as long as at least one enabled subject has an active permission with that tier and that scope. The reconciler creates it when granted, deletes it when it's no longer needed, and removes expired permissions' bindings in its periodic pass. The proxy stops sending an expired permission's group instantly, without waiting for that pass.
Optional hardening
The chart ships a ValidatingAdmissionPolicy that reserves bindings to kubelatch-* ClusterRoles for the reconciler, so nobody can hand-create one. See Security model.