kubectl auth can-i — testing RBAC decisions
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
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
- CI pipeline runs without RBAC verification. The
pipeline runs
kubectl applyand fails at admission. The fix is to verify before running. - Operator impersonates a user without authorization.
The operator has the
impersonateverb onusers, so they can act as anyone. A compromised operator account is a full cluster compromise. The fix is to restrictimpersonateto a small set of admin SAs. - 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
sudoanalogue that impersonation provides.
Quiz
Knowledge check · 4 questions
Q1. What is required for a user to use `kubectl --as=alice` to impersonate another user?
Q2. `kubectl auth can-i --list` returns the *intersection* of all bindings for an identity, not the union.
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.
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.