Skip to content

RBAC

The RBAC extension answers two questions about the Kubernetes cluster you are connected to: which identity the API server authenticated you as, and what that identity is actually allowed to do. It asks the cluster directly using the Kubernetes SelfSubject* review APIs, so you get an answer even when your account cannot read a single Role or RoleBinding.

Everything the extension shows is about you - the identity in the active cluster's kubeconfig context. It is read-only: it reports what the API server says your access is, and it can never change permissions.

RBAC is a Pro feature - without a Pro license the workspace shows a "RBAC requires a Pro license" notice with an Upgrade button. See Plans & Pro.

Setup

  1. Install the RBAC extension from Settings → Extensions (see Extensions). It starts automatically.
  2. Connect a Kubernetes cluster as usual. The extension has no connection or credentials of its own and does not appear on the Sources page - it works against whichever cluster is currently active.
  3. The extension shells out to the kubectl CLI. If kubectl is not installed, the workspace shows a "Setup required" card reading "RBAC needs a CLI tool to show its data." with kubectl listed, and an Install button when Kunobi's tool manager can install it for you.

Your account needs no special permissions for the reviews themselves. By default every authenticated user may call the SelfSubject* APIs about themselves, and clusters normally grant this through a standard cluster-wide binding; a cluster that has removed that binding will refuse the probes. Listing namespaces is a separate, ordinary permission check - see Troubleshooting for what a restricted account sees.

Browsing Your Access

Open the Kubernetes data page, open the workspace selector (press W), and pick RBAC. The sidebar replaces the standard Kubernetes kinds with three entries:

  • Who am I - one row: the identity the active cluster authenticated. Columns are Cluster, User, Groups (how many groups you are in), Namespaces, and Status.
  • Overview - your effective access across every probed namespace, one row per namespace, resource and API group you hold a grant on. Columns are Namespace, Resource, API Group, and Actions.
  • Namespaces - one row per probed namespace, with columns Namespace, Resources and Status (the namespace's own phase, Active or Terminating).

The Namespaces column on Who am I counts the namespaces that have a rules-review answer, which is not the same as the namespaces you have access in, and not the same as the namespaces that answered this probe: a namespace whose review failed but whose earlier answer was kept still counts. Only namespaces with no answer at all are excluded. Read Coverage in the row's detail before drawing conclusions from it.

Selecting a namespace row and drilling in opens a fourth view, Namespace Access, which is the Overview grid scoped to that one namespace: Resource, API Group, Actions. It is reachable only by drilling in, so it is not offered in the sidebar or the kind filter.

These behave like other resource views - sort them, search them, and open a row to see its details in the sidebar. Search is per-column and covers only the columns marked searchable, which is a subset of what each view displays: Who am I searches cluster, user and status; Overview searches namespace, resource and API group; Namespace Access searches resource and API group; Namespaces searches namespace and status. The Actions and Resources columns are displayed but not searchable.

The API Group column shows the group a grant belongs to. Kubernetes names the original core group with an empty string; the extension displays it as core, so core resources like pods and configmaps read core rather than a blank cell.

The Resources Column

On the Namespaces view, Resources is how many distinct resources you can touch in that namespace, but it also carries a state that is not a count:

ValueMeaning
5A rules review returned five distinct resources.
5 (partial)A review returned five, but the cluster marked it incomplete - see What an access answer proves.
unknownThe review did not answer for this namespace and there was no earlier result to fall back on. Not the same as no access.

A number in this column does not tell you when it was measured. If a namespace's review fails but an earlier one succeeded, the previous number is kept and displayed plainly, so a stale count is indistinguishable from a fresh one in the table. That is deliberate - a marker appearing and vanishing between probes would be its own kind of noise - and the row's detail is where the provenance lives. Open the row and read its Resources field whenever the number matters.

The column sorts numerically; rows reading unknown sort last in ascending order.

Reading the Actions Matrix

The Actions column is a fixed matrix of the seven standard Kubernetes verbs, in this order: get, list, watch, create, update, patch, delete. A verb you hold is green; one you do not is grey, with a tooltip naming it as not granted. Two things extend the matrix:

  • A wildcard verb grant (*) lights every chip and appends a * chip of its own.
  • Verbs outside the standard seven - deletecollection, bind, escalate, custom subresource verbs - are appended as extra green chips when you hold them.

The matrix column cannot be sorted, since a set of verbs has no meaningful order.

Wildcards are only expanded for verbs. A rule that grants a wildcard resource or API group is shown literally, as a row whose Resource or API Group reads *. A cluster-admin-style grant therefore appears as a single * / * row rather than as a row per resource, and searching that grid for secrets will not find it.

The matrix tells you which actions you hold, not which objects you hold them on. A verb can be granted on every object of a resource or on a handful of named ones, and the chip looks the same either way. Open the row and read Names for the object scope - see Details.

Status Values

The Status column on Who am I reflects a live probe of the cluster, not merely whether Kunobi has a cluster selected:

StatusMeaning
Not fetchedNo probe has run for this cluster yet.
ConnectingA probe is in flight for a cluster that is not currently connected.
ConnectedAt least one of the identity and namespace probes got an answer back.
UnreachableBoth the identity and the namespace probe failed.

A cluster is only ever called Connected once kubectl actually reached it, so the dot is a real signal rather than a restatement of your Kunobi connection. Note that Connected only requires one of the two probes to succeed, so it does not by itself mean every part of the view has data.

Connecting shows on a first probe and again on any probe of a cluster that is not already Connected - so a cluster that went Unreachable returns to Connecting when it is retried. Once it reads Connected, later refreshes leave it there for the whole probe, so the column is not a live indicator of whether a refresh is running.

Details

Selecting a row opens an Overview tab in the details sidebar. Because these are rows computed from the review APIs rather than objects stored in your cluster, there is no Events tab, and the YAML tab is read-only - there is nothing in the cluster to write back to. Empty values render as -.

Who am I shows three sections:

  • Identity - Cluster, User, UID, Status (with the same colored dot), Namespaces, and Coverage.
  • Groups - every group the API server attached to your identity, as chips. Most access usually arrives through group membership rather than being bound to your username directly, so this list is normally where the real answer lives.
  • Non-resource URLs - grants on URL paths that are not Kubernetes objects, such as /healthz or /version, shown as verbs followed by the paths they cover. The section is hidden when you hold none. These are collected from every probed namespace and de-duplicated, so the list is your whole cluster-wide set rather than one namespace's.

Coverage reports gaps in the sweep. It reads complete when there are none. Otherwise it leads with how many namespaces have an answer and names each gap, joined by ; - for example 12 answered; 2 namespaces did not answer, or 12 answered; namespace list is stale (namespaces timed out after 20s); 37 beyond the probe cap were not checked. The three gaps it reports are a namespace listing that failed, namespaces with no answer at all, and namespaces dropped by the probe cap.

Coverage is about missing answers, not stale ones. A namespace whose review failed but kept an earlier answer is not counted as a gap, so complete means every namespace has an answer, not that every answer is current. For per-namespace freshness, read the Resources field on that namespace's own row.

Overview and Namespace Access rows share a grant detail:

  • Grant - Namespace, Resource, API Group, Actions (the verbs you hold, as chips), and Names (the object scope, below).
  • Granting rules - a table with an Actions and a Resource names column, showing the contributing rules rather than one merged line. One line of the matrix is often the sum of several rules, and this table is where they come apart: a broad rule granting get, list, watch on everything, and a narrow one granting get on two named objects, are two rows here. Rules that share the same verbs and the same object names collapse into one row, so this lists distinct rule shapes rather than one row per rule object in your cluster.

Names is the object scope of the grant, and object scope belongs to a verb, not to the row as a whole. When every action shares the same scope it is stated once - either the object names, or all objects when nothing limits it. When the actions differ, Names breaks down per action instead, one line each, in alphabetical order by action, reading all objects or the names that apply to that action. So a grant where one rule allows get on every ConfigMap and another allows delete on just app-config reads:

delete → app-config
get    → all objects

rather than implying either scope covers both.

Namespaces rows show a single Namespace section: Cluster, Namespace, Resources, Status. Here Resources is annotated with where the number came from. A plain number is a current, complete answer. Otherwise the notes appear in brackets, joined by ;: may be incomplete when the cluster could not fully enumerate your rules, and from last successful check, because <reason> when this probe's review failed and an earlier number was kept. When there is no number at all it reads Unknown (<reason>). The reason is the underlying probe error, so it looks like Unknown (rules-review timed out after 20s) or names the failing kubectl command and its exit code.

Drilling Into a Namespace

From the Namespaces view, open a namespace row to see only that namespace's grants:

  • Double-click the row. A single click only selects it.
  • Or, with the table focused, press Enter on the selected row.
  • Or select the row and press Shift+R, or use the Resources button in the action bar.
  • Or select the row and run Resources from the command palette.

Kunobi navigates to Namespace Access scoped to that namespace and adds a breadcrumb named after it. Press Escape to go back; if a search term or a multi-row selection is active, Escape clears that first. See Drilldown for how breadcrumbs and back navigation work generally.

Drilling into a namespace whose review has no answer at all raises an error instead of an empty grid, since an empty grid would read as "no access". Drilling into one that kept an earlier answer shows that answer with no staleness marker on the grid - the Namespaces row's detail is the only place that distinction appears.

Resources is the only RBAC-specific action. Alongside it the action bar offers the standard Overview (o) and YAML (y) buttons for the selected row. Events and Delete are deliberately absent on RBAC rows: there is no cluster object behind them to read events from or delete.

How Access Is Computed

When you open an RBAC view, the extension probes the active cluster with three kinds of kubectl call, each pinned to that context's kubeconfig and context name so a probe can never cross clusters:

  1. kubectl auth whoami for your identity - username, UID and groups.
  2. kubectl get namespaces for the namespace list and each namespace's phase.
  3. One SelfSubjectRulesReview per namespace for the rules that apply to you there.

The API server evaluates every Role, ClusterRole and binding that touches you or your groups and returns the result, which is why this works for an account that cannot read those objects itself. SelfSubjectRulesReview only answers about one namespace at a time, which is why access is presented namespace by namespace throughout the extension.

Because each namespace is asked separately, a grant that comes from a ClusterRole bound cluster-wide is returned by every namespace's review, and so appears as a row under every probed namespace rather than once. On a cluster with many namespaces, one such binding can account for most of the rows in the Overview.

At most 200 namespaces are probed per cluster, taken in alphabetical order. Any beyond that are absent from every view, and the count of what was dropped is reported in Coverage.

The per-namespace reviews run concurrently, but no more than five kubectl processes run at once across the whole extension, so a cluster with many namespaces drains steadily instead of spawning a burst of subprocesses. Each probe is given 20 seconds, and that budget covers waiting for a free process slot as well as the call itself - on a cluster with hundreds of namespaces, reviews near the back of the queue can use up their budget before kubectl even starts. A review that runs out of time never reports zero access: it either keeps the previous number or reads unknown.

Refreshing

Probing is bounded to the time you are actually looking at RBAC:

  • Opening an RBAC view probes the active cluster immediately. Switching between Who am I, Overview and Namespaces re-probes, as does switching the active cluster.
  • While a view stays open, the extension re-probes every five minutes as a safety refresh.
  • Leaving the RBAC views stops the probing. The data you last saw stays in place, so returning shows it immediately and then refreshes.

There is no manual refresh button and no "last updated" timestamp in the views - reopening a view is the way to force a fresh answer.

When a refresh partly fails, the previous answer is kept rather than blanked. A namespace whose review fails keeps its last successful count, and that namespace's detail says so. If the kubectl get namespaces listing fails, nothing derived from it is refreshed at all: the namespace list, every per-namespace result, and the probe-cap count all stay as they were, and Coverage reports the list as stale. In that state the other clauses of Coverage describe the earlier probe rather than the current one.

What an Access Answer Proves

The grid answers a precise question, and it is easy to read more into it than it says.

It is about you, and only you. Every answer comes from a SelfSubject* review, which by construction reports on the caller. There is no way to ask what a different user, group or service account is allowed to do.

A green verb does not say which objects it covers. The matrix shows the actions you hold on a resource; the object scope lives in the row's Names field, broken down per action when the actions differ. Read it before concluding you can act on a specific object.

It is an enumeration of what authorization allows, not a rehearsal of the action. The extension never attempts the operation. A request the review reports as allowed can still be rejected later by admission-time policy, by a validating webhook, or by a quota, none of which the authorization layer knows about.

unknown is not zero, and a partial answer is not a complete one. A namespace reading unknown was never successfully reviewed, and says nothing about your access there. A count marked (partial) means the cluster itself reported that it could not fully enumerate your rules, so there may be access the list does not show.

A number can be old. Nothing in any table marks a value as stale. A retained count looks exactly like a fresh one, and Coverage: complete only means every namespace has an answer, not that every answer is current. When freshness matters, open the namespace row and read its Resources field, which names the probe the number came from.

The Resources count is a count of distinct resource names, not of permissions or of grid rows. It ignores the API group and does not expand wildcards, which produces some counter-intuitive numbers:

  • A wildcard grant (resources: ["*"]) counts as 1 - so a full cluster-admin can show the smallest non-zero count there is.
  • pods and pods/log count as two, since subresources are separate names.
  • The same resource name in two API groups counts once here, while the namespace's own grid shows it as two rows.

Troubleshooting

Three full-pane gates can replace the views entirely, and they are checked in this order - the first one that applies is the one you see.

"RBAC requires a Pro license" - checked first, so it appears even when no cluster is connected and kubectl is missing. The workspace is Pro-gated, and the gate is enforced in the extension itself, not only in the interface: while it is locked no kubectl probing runs at all and the collected data is discarded. Upgrade opens the pricing page. Access is restored as soon as the license is applied, without restarting the app.

A cluster-connection screen - checked second. RBAC has no data source of its own, so it shows whatever the standard Kubernetes connection gate reports: "No Cluster Selected" with a Select Cluster button when nothing is picked, and equally "Disconnected" (with a Connect button), "Connecting...", "Reconnecting...", "Disconnecting...", "Cluster Not Found", "Connection Error", or "Connection Required". Resolve the cluster connection and the RBAC views return.

"Setup required", naming kubectl - checked last. The extension drives the kubectl CLI and cannot produce anything without it. Use Install on that card if Kunobi can install it for you, otherwise install kubectl yourself and make sure it is on your PATH; the card also links to Settings → Tools. If an install attempt failed, a red dot appears next to the tool and hovering it shows the error.

Past those gates, a probe that cannot produce data replaces the table with an "Unable to Load Resources" screen. The heading is always the same; the message under it says which failure occurred, above the line "The source returned this error". Because the error replaces the table, you never see it and an Unreachable Status cell at the same time.

These screens only appear when there is nothing to show. If an earlier probe left data behind, that data is kept on screen instead - stale results are treated as more useful than a banner, so a failure you would expect to see reported can be silently absorbed while the previous answer is still displayed.

The message names a failing kubectl command, or a step that timed out - both the identity probe and the namespace listing failed. The text is the failing command's own error output wrapped with the command and its exit code, or a message naming the step that exceeded its 20-second budget. When both probes fail for different reasons, only the identity probe's error is shown. Common causes are an expired credential or an authentication plugin that cannot refresh one, a cluster that is not reachable from your network, or a slow cluster exhausting the timeout.

Access in "<namespace>" is unknown: the rules review did not answer (<reason>). - you drilled into a namespace that has no rules-review answer at all, so there is nothing to show and an empty grid would read as "no access". The reason in brackets is the underlying probe error. Reopen the view to re-probe; if it persists, the cause is usually the per-probe timeout on a large or slow cluster.

Could not list namespaces: <error> - kubectl get namespaces failed and no earlier list survives to show instead. The reviews about yourself keep working, so the cluster still counts as Connected and Who am I answers, but without a namespace list there is nothing to run the per-namespace reviews against. This is the usual symptom of a tightly restricted account: listing namespaces is an ordinary permission check, unlike the SelfSubject* reviews. If an earlier probe did return a list, that list stays on screen instead of this error, and Coverage reports it as stale.

Could not start the RBAC probe for "<cluster>": <error> - the extension could not be asked to probe, so no data will arrive at all. This normally means the RBAC extension is not running; check it under Settings → Extensions. As above, it is suppressed when there is still data on screen from an earlier probe.

The User column is empty - the identity probe failed while the namespace listing succeeded, so the cluster counts as reached but no identity came back. kubectl auth whoami needs a reasonably recent cluster and kubectl; an older pairing may not support it. This only shows as empty on the first probe of a cluster: once an identity has been resolved, a later failed identity probe keeps the previous value rather than blanking it.

The tables are empty and no error is shown - the probe returned no grants for your identity. The failure modes that used to look like this are now reported: a namespace whose review failed outright reads unknown rather than 0, and a failed namespace listing raises an error of its own when there is nothing to show. Still check Coverage on the Who am I row before concluding you hold nothing, since an answer can be complete in the sense that every namespace replied while some replies are old.

A namespace is missing from the list - at most 200 namespaces are probed per cluster, taken in alphabetical order. Coverage reports how many were dropped.

Limitations

  • Your identity only. No "can this other user do X" - the SelfSubject* APIs report on the caller, and nothing in the extension asks about anyone else.
  • One cluster at a time. Views always follow the active cluster; there is no side-by-side comparison across clusters.
  • 200 namespaces per cluster, alphabetically. Namespaces beyond that limit are absent from every view, including the namespace list itself; the shortfall is reported in Coverage rather than being silent.
  • Wildcard resources and API groups are not expanded. A * grant stays a single * row instead of being enumerated into the resources it covers.
  • Cluster-wide grants are repeated per namespace. Every review is namespace-scoped, so a ClusterRole-derived grant appears once under each probed namespace, and grants on cluster-scoped resources such as nodes or persistentvolumes are shown with a namespace name that carries no meaning for them.
  • A partial answer is flagged, not completed. When the cluster reports that it could not fully enumerate your rules, the count is marked (partial) and the answer is shown as-is. The extension cannot fill in what the cluster would not enumerate.
  • Stale values are kept and not marked in any table. A namespace whose review fails keeps its last successful count, and a failed namespace listing keeps the whole previous namespace set. This avoids flickering to zero, but the only place provenance appears is a namespace row's Resources detail. Coverage does not report retained values, and the Namespace Access grid shows a retained namespace's grants with no indication they are old.
  • Read-only. The extension inspects access; it cannot grant, revoke or test permissions. To change RBAC, edit the underlying Role, ClusterRole and binding objects in the standard Kubernetes views.
  • No export. There is no built-in way to export the access grid; copy from the table or the details sidebar.
Available for:
Apple macOS logomacOSMicrosoft Windows logoWindowsLinux logoLinux
Download Kunobi