Skip to main content
When a Cloud user clicks into a cluster, the control plane injects their identity onto the request and the in-cluster Radar pod (running with --auth-mode=proxy) impersonates them on the K8s API. Per-user RBAC just works - via standard K8s impersonation, not a custom permission system.

The header contract

For every request through the tunnel, the control plane:
  1. Strips inbound X-Forwarded-* to prevent spoofing.
  2. Injects:
    • X-Forwarded-User: <user_id> (e.g. user_01HF...)
    • X-Forwarded-Groups: cloud:<role>,cloud:org:<org_id>,cloud:user:<user_id>
<role> is one of owner, member, viewer - the user’s Cloud role in the org that owns the cluster. The in-cluster Radar (under RADAR_CLOUD_MODE=true) is forced to --auth-mode=proxy with these header names pinned. The chart enforces this; you can’t override it without un-cloud-mode-ing the in-cluster Radar.

The default RBAC

The chart ships three ClusterRoleBindings out of the box: K8s itself decides what each ClusterRole permits. view is read-only for namespaced resources. edit adds writes. admin adds RBAC operations.

Overriding the defaults

The chart’s cloud.defaultRbac.* block lets you swap each binding:
To disable a binding entirely (e.g. you want only owners to have access, no members or viewers):
Members and viewers will then hit 403s when they try to do anything in the cluster. The Cloud UI still shows the cluster in the list - it’s the K8s API that’s saying no.

Per-user bindings

If you need finer control than role-level (e.g. specific user can edit deployments but only in apps/* namespaces), bind directly to the per-user group:
Find a user’s user_id in:
  • The audit log row metadata.
  • The user’s PAT page (their own ID is shown at the top).
  • Owner’s view of Settings → Organization → Members (hover the row).

Per-org bindings

Every request also carries cloud:org:<org_id> in the groups header. This is mostly useful for clusters that move between orgs - typically you wouldn’t need to bind to it directly. But if you ever need “any user from this org can do X”, that’s the hook.

Auditing what the in-cluster Radar did

K8s itself logs impersonated requests in audit.k8s.io if you’ve enabled the audit policy on the apiserver. The user ID and groups are present in the audit log entry, so you can correlate “user X did Y” against the Cloud audit log (which shows control-plane actions) and the K8s audit log (which shows in-cluster actions).

Things to watch out for

  • Default admin is broad. It can read Secrets, mutate RBAC, drain nodes. If you have non-admin owners, swap cloud:owner to a custom ClusterRole.
  • view doesn’t see Secrets. That’s K8s view definition, not ours. If you want viewers to see Secret names without values, use a custom ClusterRole that grants get/list on secrets (which lets them see Secret data too - K8s doesn’t have field-level RBAC). Since Secret data is redacted by Radar before display, this is usually safe but think it through.
  • Helm write needs more than edit. Helm install / upgrade / rollback / uninstall need broad write access, including Secrets (Helm releases are Secrets). The chart’s default member → edit is intentionally not enough for Helm writes; opt in via a custom binding if you want members to manage Helm.

See also