When a Cloud user clicks into a cluster, the Hub injects their identity onto the request and the in-cluster Radar pod (running withDocumentation Index
Fetch the complete documentation index at: https://radarhq.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
--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 Hub:- Strips inbound
X-Forwarded-*to prevent spoofing. - 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:| Cloud role | Impersonated as group | Bound to ClusterRole |
|---|---|---|
| Owner | cloud:owner | admin (K8s built-in) |
| Member | cloud:member | edit (K8s built-in) |
| Viewer | cloud:viewer | view (K8s built-in) |
view is read-only for namespaced resources. edit adds writes. admin adds RBAC operations.
Overriding the defaults
The chart’scloud.defaultRbac.* block lets you swap each binding:
Per-user bindings
If you need finer control than role-level (e.g. specific user can edit deployments but only inapps/* namespaces), bind directly to the per-user group:
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 carriescloud: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 inaudit.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
adminis broad. It can read Secrets, mutate RBAC, drain nodes. If you have non-admin owners, swapcloud:ownerto a custom ClusterRole. viewdoesn’t see Secrets. That’s K8sviewdefinition, not ours. If you want viewers to see Secret names without values, use a custom ClusterRole that grantsget/listonsecrets(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 defaultmember → editis intentionally not enough for Helm writes; opt in via a custom binding if you want members to manage Helm.
See also
- Authentication - how proxy / OIDC mode work generally.
- Connecting a cluster - the chart values that enable cloud-mode.
- Organizations & roles - the role definitions that drive these groups.