Skip to main content
RunBook Academy

KubernetesLVIII · RBACRBAC

kubectl auth can-i — testing RBAC decisions

Advanced⏱ ~14 minkubectl

What you'll learn

  • Use `kubectl auth can-i` to test RBAC decisions for any identity
  • List the full set of permissions for an identity in a namespace
  • Identify impersonation patterns (--as, --as-group) and their safety implications
  • Audit a cluster by testing every SA against the permissions it should have

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

kubectl auth can-i is the standard tool for verifying RBAC decisions. It answers the question: can this identity perform this action on this resource? The identity can be the current user, a specific ServiceAccount, or an impersonated user/group. This lesson covers the verb × resource × namespace matrix, the impersonation flags, and the production patterns for CI/CD and audits.

The basic syntax

kubectl auth can-i <verb> <resource>
                   [--namespace <ns>]
                   [--as <user>]
                   [--as-group <group>]

The output is yes or no. A yes means the RBAC authorizer would allow the request; a no means it would reject.

# Can I (current user) create deployments in prod?
kubectl auth can-i create deployments -n prod
# yes

# Can the CI SA read pods in prod?
kubectl auth can-i list pods -n prod \
  --as=system:serviceaccount:ci:ci-runner
# yes

# Can alice create clusterrolebindings?
kubectl auth can-i create clusterrolebindings \
  --as=alice --as-group=idp:dev
# no

The --as flag impersonates a user; the --as-group flag adds a group. The API server validates that the caller has the impersonate verb on the target — only cluster-admin (or a SA with the impersonate verb on users/groups/serviceaccounts) can impersonate.

Listing all permissions

The --list flag returns the full set of permissions for an identity in a namespace:

kubectl auth can-i --list -n prod \
  --as=system:serviceaccount:ci:ci-runner
Resources                                       Verbs
configmaps                                      [get, list, watch]
deployments.apps                                [get, list, watch]
pods                                            [get, list, watch]
pods/log                                        [get]
secrets                                         [get, list, watch]
services                                        [get, list, watch]
...

The output is the effective permissions: every binding that applies to the identity is combined (union) and listed. An SA bound to two Roles sees the union of both Roles’ permissions.

flowchart LR
    A[Identity] --> B[All bindings]
    B --> C[Role A rules]
    B --> D[Role B rules]
    C --> E[Union]
    D --> E
    E --> F[--list output]

Verifying CI/CD roles

A CI/CD pipeline that deploys manifests should verify its RBAC before running:

#!/bin/bash
# CI pipeline RBAC verification
set -e

REQUIRED_VERBS=(
  "create deployments"
  "update deployments"
  "patch deployments"
  "create services"
  "create configmaps"
)

for verb in "${REQUIRED_VERBS[@]}"; do
  read -r VERB RESOURCE <<< "$verb"
  if ! kubectl auth can-i "$VERB" "$RESOURCE" \
       --as=system:serviceaccount:ci:ci-runner \
       -n "$NAMESPACE"; then
    echo "FATAL: CI SA cannot $VERB $RESOURCE"
    exit 1
  fi
done

echo "All required permissions verified"

The pipeline fails fast if the SA lacks a required permission. This is the right discipline: do not run a manifest apply that will fail at admission; verify first.

Impersonation for debugging

Operators use --as to debug RBAC issues. If a user reports they cannot read a Secret, the operator impersonates the user and asks:

# Reproduce the user's issue
kubectl auth can-i get secrets -n prod \
  --as=alice --as-group=idp:dev
# no

# What can alice do?
kubectl auth can-i --list -n prod \
  --as=alice --as-group=idp:dev
# (only the user's effective permissions)

If the operator has the impersonate verb, they can also actually perform the action as the user:

kubectl get secrets -n prod \
  --as=alice --as-group=idp:dev

Auditing with auth can-i

A cluster-wide audit walks every SA and asks what it can do:

#!/bin/bash
# Audit every SA in the cluster
for ns in $(kubectl get ns -o name | cut -d/ -f2); do
  for sa in $(kubectl get sa -n "$ns" -o name | cut -d/ -f2); do
    echo "=== $ns/$sa ==="
    kubectl auth can-i --list -n "$ns" \
      --as=system:serviceaccount:$ns:$sa
  done
done | tee audit-report.txt

The output is a long list. The audit compares each SA’s effective permissions against the expected set (the SA’s documented purpose). Any discrepancy is a finding.

# Find SAs that can create rolebindings (privilege escalation)
for ns in $(kubectl get ns -o name | cut -d/ -f2); do
  for sa in $(kubectl get sa -n "$ns" -o name | cut -d/ -f2); do
    if kubectl auth can-i create rolebindings \
         --as=system:serviceaccount:$ns:$sa \
         -n "$ns" 2>/dev/null; then
      echo "ESCALATION: $ns/$sa"
    fi
  done
done

A SA that can create RoleBindings is a privilege escalation primitive — an attacker who compromises it can escalate.

Production failure modes

  1. CI pipeline runs without RBAC verification. The pipeline runs kubectl apply and fails at admission. The fix is to verify before running.
  2. Operator impersonates a user without authorization. The operator has the impersonate verb on users, so they can act as anyone. A compromised operator account is a full cluster compromise. The fix is to restrict impersonate to a small set of admin SAs.
  3. Audit compares effective permissions to expected surface, but the comparison is manual. The audit produces a long list; the operator reads it and misses an over-permissioned SA. The fix is to encode the expected surface in a CI test that fails if it is exceeded.

Cross-course references

  • The Observability course covers the audit log entries for impersonation requests.
  • The Linux course covers the sudo analogue that impersonation provides.

Quiz

Knowledge check · 4 questions

  1. Q1. What is required for a user to use `kubectl --as=alice` to impersonate another user?

  2. Q2. `kubectl auth can-i --list` returns the *intersection* of all bindings for an identity, not the union.

  3. Q3. Your audit script runs `kubectl auth can-i --list` for every SA in the cluster. The output for `ci:ci-runner` shows: `clusterrolebindings [create], rolebindings [create], secrets [get, list, watch], configmaps [...], deployments [get, list, watch, update]`. The expected set is `deployments [get, list, watch]` only. What is wrong?

    The CI SA was bound to the `cluster-admin` ClusterRole by an early Helm chart default. The chart was supposed to bind it to a custom `ci-deployer` Role with limited verbs. The cluster-admin binding was never removed.

  4. Q4. Explain what `kubectl auth can-i --list -n prod --as=system:serviceaccount:ci:ci-runner` returns and how to use it for an audit.

Passing score: 75%. Answers are checked in this browser.

Production discipline

kubectl auth can-i is the operational proof of RBAC correctness. A defensible RBAC programme runs verification in CI/CD before every deploy, runs an audit script against every SA in the cluster, and encodes the expected surface in a test that fails if the actual surface exceeds it. The --as and --as-group flags are powerful but dangerous — they must be granted only to operators who need them, and the audit log must record the impersonation. A cluster whose effective permissions are not audited is a cluster whose RBAC is not enforceable.