- Live operations - writes, exec, logs, attach, and uncached reads - run as the user through Kubernetes impersonation.
- Cached reads - including ordinary resource lists, details, timeline, and topology - are filtered by Radar using Kubernetes authorization checks. For most namespaced resources, access is namespace-wide: permission to read one kind can expose other cached kinds in that namespace. Secrets and cluster-scoped resources have separate checks. See read granularity.
The header contract
For every request through the tunnel, the control plane:- Strips inbound
X-Forwarded-*to prevent spoofing. - Injects:
X-Forwarded-User: <user_id>(e.g.user_01HF...)X-Forwarded-Groups:a comma-separated list of the groups below.
The
radar:idp:* and radar:email:* groups are the hooks the governance examples bind - they exist independently of this chart’s tier bindings.
For user requests, role, org, and user groups are also emitted under the deprecated cloud: prefix. IdP and email groups use only radar:; write new bindings against radar:*. Alert-triggered investigation turns send only radar:ai:reader; hub background jobs send only radar:system.
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.
Pod trust boundary
The Radar ServiceAccount can impersonate any Kubernetes user or group. Treat the pod as a privileged authentication proxy: restrict who can modify or exec into it, or read its ServiceAccount token. Disabling the default Cloud-user bindings does not reduce this impersonation grant.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.
Cluster-scoped resources need an extra grant
The built-inview / edit / admin roles are namespace roles - by Kubernetes design they grant nothing on most cluster-scoped resources:
So a tier bound only to a built-in role can’t see Nodes, PVs, storage, or ClusterTrustBundles - core infrastructure and trust metadata used by an observability tool. Radar’s chart closes this with a cluster-read add-on, on by default per tier (
cloud.defaultRbac.clusterScopedRead.{viewer,member,owner}, each true). It grants get/list/watch on the kinds above - no Secrets, no RBAC objects, and no PodCertificateRequests.
Pod certificate requests are opt-in
Kubernetes 1.37 serves namespacedPodCertificateRequest resources, and Radar can display them in the generic resource browser. The default Cloud tier bindings deliberately do not grant access: certificate-request metadata is more sensitive than ordinary workload inventory. A user sees these resources only where their own Kubernetes RBAC grants get/list access.
To opt in, bind a Role or ClusterRole granting get/list/watch on certificates.k8s.io/podcertificaterequests to the intended radar:viewer, radar:member, or radar:owner group. Prefer a namespaced Role when users need access only within a specific workload boundary.
Cluster-read is its own axis, separate from which namespaced ClusterRole a tier binds to:
- Turn it off for a tier to remove this add-on’s binding. With the default built-in mappings that leaves the tier namespaced-only:
clusterScopedRead.viewer: falseleaves viewers on the stockview(namespaced read) with no cluster-scoped visibility - the usual choice for a low-trust viewer tier (see security-conscious setups). With a custom*ClusterRole, the tier’s cluster-scoped reach is whatever that role grants - the flag only controls our binding. - Swapping a tier’s namespaced role does not disable cluster-read.
viewerClusterRole/memberClusterRole/ownerClusterRoleandclusterScopedRead.*are independent bindings. If you want a custom namespaced role and no infra-read, set that tier’sclusterScopedReadtofalsetoo. - A tier you’ve disabled entirely (
viewer: false) gets nothing here either - you own that tier’s RBAC.
rbac.crdGroups.karpenter, for the Capacity view), Prometheus Operator PrometheusRules (rbac.crdGroups.prometheus), and the two Cilium policy kinds CiliumNetworkPolicy and CiliumClusterwideNetworkPolicy (rbac.crdGroups.cilium, for the Traffic view’s dropped-flow panel). Other cluster-scoped CRDs that appear in topology (GatewayClass, Calico global policies, …) are not included - grant those per the CRD’s group if your tiers need them.
Owner node cordon/drain is a separate cluster-scoped write and is off by default - enable with cloud.defaultRbac.nodeOps: true.
Radar Cloud background identity
Some Radar Cloud features run without a person behind them: the alerts worker (which polls each cluster for issues) and the timeline puller (which records the cluster’s change history in Radar Cloud). They send only theradar:system group, and the chart binds that group for them:
The chart supplies read-only permissions. These grants are independent of
cloud.defaultRbac: they stay when you turn the tier bindings off, so alerts and the timeline keep working when IdP groups decide cluster access.
To remove all of the chart’s default background grants, set cloud.systemRbac (default true) to false:
radar:system yourself. If a cluster lacks background access, upgrade its Helm chart or bind radar:system yourself.
- Change it through the chart value. A binding you edit or delete with
kubectlcomes back on the nexthelm upgradeor GitOps sync. - Upgrades with
--reuse-valuesfrom a chart that predatescloud.systemRbacleave it off, so an existing install never gains cluster-wide Secret read without someone choosing it. Setcloud.systemRbac=trueon those installs. Fresh installs, plainhelm upgrade,--reset-then-reuse-valuesand GitOps get the default. - Investigations use separate access. See AI investigation access.
Include
radar:system in access reviews. Its Secret read covers every namespace: Kubernetes RBAC cannot narrow it to Helm’s Secrets.AI investigation access
AI investigations are read-only. Hosted investigations, whether started by a person or an alert, require Radar 1.16.0 or later on the cluster. If Radar is older or offline, the investigation cannot proceed; upgrade or restore the connection first.Requests from a person use their access
Starting an investigation or asking a follow-up uses that person’s Kubernetes identity and groups, including their Radar role and IdP groups. A user restricted to certain namespaces gets an investigation restricted to those namespaces too. This also applies when someone follows up on an investigation started by an alert. If Radar Cloud cannot confirm the person’s access, the request stops and asks them to sign in again. It does not use a broader identity instead.Alert-triggered investigations use radar:ai:reader
The initial alert-triggered turn sends only radar:ai:reader, without a person’s groups or a Radar role. Kubernetes audit logs record these reads as radar:ai:<org_id>. By default, the chart grants:
These grants are independent of
cloud.defaultRbac, so disabling the human tier bindings does not remove them. Changing viewerClusterRole does not affect them, but roles labelled aggregate-to-view widen the AI role too. Review those roles before assuming it cannot read Secrets or other sensitive data.
To replace the chart’s default grant with your own bindings:
radar:ai:reader still apply. For example, use RoleBindings to limit it to selected namespaces. With no grants, alert-triggered investigations cannot read the cluster. To stop automatic analysis, clear Include AI analysis on your alert rules under Settings → Organization → Notifications.
When upgrading from a chart that predates cloud.aiRbac, use --reset-then-reuse-values to apply new defaults while preserving your supplied values. Plain --reuse-values can leave the key absent, which creates no default grant. An explicit cloud.aiRbac=false is preserved by either upgrade.
Who can see the results
Sharing an investigation makes its whole transcript visible to the organization. Alert-triggered investigations are organization-visible from the start. Transcripts contain results collected under each asker’s access, which can exceed another member’s own Kubernetes access. See investigation sharing. MCP clients, such as Claude Desktop and Cursor, use the user’s own Cloud identity and groups.Overriding the defaults
The chart’scloud.defaultRbac.* block lets you swap each binding:
Locking down for security-conscious orgs
The defaults optimize for “an observability tool should show infrastructure”: every tier gets cluster-scoped read out of the box, and writes still flow through each tier’s K8s role. If your security posture is tighter, these are the levers - each is a smallvalues.yaml change, no custom roles required:
Make the viewer tier namespaced-only (most common). Viewers keep read access to the namespaces their K8s identity allows, but cannot enumerate Nodes, PVs, or storage cluster-wide:
owner → admin reads Secrets and mutates RBAC in every namespace (namespace-scoped, not cluster-wide). Point owners at a tighter custom ClusterRole; cluster-read stays independent, so you keep infra visibility unless you also disable it:
nodeOps) is already false by default. Leave it off unless owners genuinely operate nodes from Radar - K8s RBAC cannot scope patch nodes to just the cordon field (it also permits relabeling/tainting nodes) and cannot scope pods/eviction to a single node’s pods (it permits evicting any pod in any namespace; PodDisruptionBudgets bound the impact only where they exist).
What you cannot do through values.yaml is change which cluster-scoped kinds the add-on grants (it’s a fixed, Secret-free infra set). If you need a different set for a tier - say Nodes but not PVs - set that tier’s clusterScopedRead to false and bind your own ClusterRole to the radar:<tier> group (recipe below). The radar:* groups exist independent of this chart, so your binding composes with the built-in namespaced one.
Choosing a governance model
There are two coherent ways to combine the tier defaults with group-based bindings. Both are fully supported; they differ in where cluster access is governed, and you can move from the first to the second at any time. Mixed (the default): tiers for your operators, IdP groups for scoped access. Your platform team holds Owner/Member and rides the default tier bindings - cluster-wide access through the upstream-maintainedadmin/edit roles, zero binding authoring. External or namespace-scoped users (vendor teams, contractors) get their tier binding disabled (viewer: false) and access exclusively through radar:idp:<group> / radar:user:<id> bindings you author. Each population sits on the mechanism built for it. The tradeoff: two systems of record - operator access is governed by Radar Cloud membership roles (visible in the Cloud UI and audit log), scoped access by your IdP groups and RBAC manifests.
Full-IdP: every human’s cluster access flows through your IdP groups.
For organizations whose access reviews require a single source of truth, disable all three tier bindings and bind your own groups end to end:
- Cloud roles don’t disappear - they govern the product, not the cluster. Owner/Member/Viewer still control billing, member management, SSO, cluster lifecycle, and owner-only product surfaces: Radar’s settings, its Argo CD and Kubecost connections, audit settings, agent updates, and the OCI chart sources Radar checks for Helm upgrades. The mental model: Cloud role = control-plane permissions; Kubernetes bindings = cluster access. The tier bindings are merely the default cluster access, and they’re optional.
- The add-on grants ride the tier bindings. Cluster-scoped read,
nodeOps, and the Helm add-on roles bind to tier groups - with all tiers disabled, none of them render for people, and you own those grants in your own ClusterRoles (see the recipe above for the cluster-read set). - Background and AI access stay separate. Disabling human tier bindings leaves the chart’s grants for
radar:systemandradar:ai:readerin place. Review them separately, especially the background identity’s cluster-wide Secret read.
Full-IdP for new clusters: the organization setting
Instead of editing chart values per cluster, an owner can make IdP groups the default for new clusters with the Cluster access setting (auth.oidc.clusterAccess on a self-managed hub). Fresh installs then add cloud.defaultRbac.create=false. Existing clusters are never changed; when you connect a cluster that already runs Radar, turn on Already running Radar in this cluster? in the connect wizard to keep its bindings.
Switching an existing cluster to IdP groups
Do it in this order, or everyone loses access until a binding exists:-
Bind your groups in the cluster (
radar:idp:<group-id>, see IdP group-based access). -
Check what each group alone is allowed. Checking in Radar doesn’t prove it: the tier bindings still grant access until you remove them, and Kubernetes RBAC is additive, so a binding that names the wrong group looks fine. Ask Kubernetes about the group on its own:
An empty list means the binding doesn’t match.
kubectlrequires--aswith--as-group; the user name is arbitrary. -
Upgrade the cluster to a Radar chart with the
radar:systembinding, then remove the tier bindings:
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 carriesradar: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).
I can’t see Nodes / PVs / StorageClasses
If a tier can’t see cluster-scoped resources, its bound role doesn’t grant them. Most likely:- That tier’s
clusterScopedReadis off - setcloud.defaultRbac.clusterScopedRead.<tier>: true(the default). - You’re on an older chart that predates the cluster-read add-on - upgrade, or grant the reads directly (below).
radar-cluster-read, so reusing that name would make kubectl apply overwrite the Helm-owned object. Use radar-cluster-read-custom:
Things to watch out for
- Default
adminis broad within namespaces, but not cluster-wide. It reads Secrets and mutates RBAC in every namespace, but as a namespace role it grants nothing cluster-scoped on its own - no Node read, no node drain (that’s the opt-innodeOpsadd-on), no PV/StorageClass. If you have non-admin owners, swapradar:ownerto a custom ClusterRole. - Secret read permission includes values. The built-in
viewrole denies Secrets. Grantingget/listexposes their encodeddatain Radar’s generic resource UI and API; Kubernetes has no names-only permission. MCP redaction does not protect that separate surface. - Built-in roles are aggregation targets.
view/edit/adminare auto-reconciled and acceptaggregate-to-*labels, so third-party charts (metrics-server, kyverno, some operators) can widen what a tier effectively holds - the tier’s scope drifts with cluster contents, not just with this chart. Audit withkubectl auth can-i --list --as-group=radar:viewer --as=xif you need certainty. - Helm runs as you. Helm install / upgrade / rollback / uninstall, and viewing a release’s values and manifests, run with your own Kubernetes identity; your Cloud role doesn’t gate them. Radar enables the Helm write actions in a namespace when you can create Secrets there (Helm stores each release as a Secret), and Kubernetes checks every resource the chart touches. With
rbac.helm=trueand the tier bindings on, the chart also binds the Helm add-on roles to the owner and member tiers; in Cloud mode it grants Radar’s own ServiceAccount no write access for Helm.
A user sees an empty cluster
If a user can’t list Pods or Deployments in any namespace, Radar shows a banner - “You can’t read any namespace in this cluster” - with the groups the cluster sees for them, so they can tell an admin which group to bind. On a large cluster the banner can take a page reload to appear the first time.See also
- Authentication - how proxy / OIDC mode work generally.
- Connecting a cluster - the chart values that enable cloud-mode.
- IdP group-based access - where the
radar:idp:<group>subjects come from and how to make your IdP emit them. - Organizations & roles - the role definitions that drive these groups.