Skip to main content
RunBook Academy

KubernetesLIX · kubectl authkubectl auth

kubectl auth can-i — verifying RBAC decisions in practice

Advanced⏱ ~14 minkubectl

What you'll learn

  • Use `kubectl auth can-i` to verify any RBAC decision for any identity
  • List the full set of permissions for a SA in a namespace with `--list`
  • Test subresources (`pods/log`, `pods/exec`) with the correct verb
  • Build CI/CD verification and audit scripts using `kubectl auth can-i`

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 kubectl front-end for the SubjectAccessReview API. It asks the API server: “would this identity be allowed to perform this action?” The answer is the verification of every RBAC decision in production. This lesson covers the practical use: the flags, the patterns for CI/CD, the audit patterns, and the failure modes.

The flags

kubectl auth can-i takes a verb, a resource, and an optional namespace. The impersonation and listing flags control the identity being tested.

kubectl auth can-i <verb> <resource>
  [-n <namespace>]
  [--as <user>]
  [--as-group <group>]
  [--subresource=<subresource>]
  [--list]
FlagEffect
--as <user>Impersonate a specific user
--as-group <group>Impersonate a member of a specific group
--listReturn the full set of permissions
--subresource=<subresource>Test a subresource (e.g., pods/log)
-n <namespace>Scope to a namespace
--quietExit code only (1 = no, 0 = yes); suppress output

The output is yes or no. With --list, the output is a multi-line table of resources × verbs.

# Single permission check
kubectl auth can-i create deployments -n prod
# yes

# Impersonate a SA
kubectl auth can-i list pods -n prod \
  --as=system:serviceaccount:prod:api
# yes

# Subresource
kubectl auth can-i create pods/exec -n prod \
  --as=system:serviceaccount:prod:debug
# yes

# Full permission list
kubectl auth can-i --list -n prod \
  --as=system:serviceaccount:prod:api
# Resources                                       Verbs
# configmaps                                      [get]
# pods                                            [get, list, watch]

Verifying CI/CD permissions

A CI/CD pipeline should verify its SA’s permissions before running manifests:

#!/bin/bash
# verify-rbac.sh — CI/CD RBAC verification

NAMESPACE="${NAMESPACE:-prod}"
SA="system:serviceaccount:ci:ci-runner"

# Required verbs × resources
declare -a REQUIRED=(
  "get configmaps"
  "get secrets"
  "create configmaps"
  "create secrets"
  "create deployments"
  "update deployments"
  "patch deployments"
)

FAILED=0
for req in "${REQUIRED[@]}"; do
  read -r VERB RESOURCE <<< "$req"
  if ! kubectl auth can-i "$VERB" "$RESOURCE" \
       --as="$SA" -n "$NAMESPACE"; then
    echo "MISSING: $VERB $RESOURCE"
    FAILED=$((FAILED+1))
  fi
done

if [ $FAILED -gt 0 ]; then
  echo "RBAC verification failed: $FAILED missing permission(s)"
  exit 1
fi
echo "RBAC verification passed"

The pipeline fails fast if the SA lacks a required permission. The CI/CD run does not waste time applying manifests that will be rejected at admission.

flowchart LR
    A[CI/CD pipeline] --> B[verify-rbac.sh]
    B -->|pass| C[Apply manifests]
    B -->|fail| D[Fail with diagnostic]
    C --> E[Success]
    D --> F[Operator fixes RBAC]

The --subresource flag

Subresources require their own permission. The --subresource flag tests them explicitly:

# Read pod logs
kubectl auth can-i get pods -n prod \
  --as=system:serviceaccount:prod:debug \
  --subresource=log
# yes

# Exec into a container
kubectl auth can-i create pods -n prod \
  --as=system:serviceaccount:prod:debug \
  --subresource=exec
# yes

# Drain / evict
kubectl auth can-i create pods -n prod \
  --as=system:serviceaccount:prod:drain \
  --subresource=eviction
# yes

# Scale a Deployment
kubectl auth can-i update deployments -n prod \
  --as=system:serviceaccount:prod:autoscaler \
  --subresource=scale
# yes

A role that grants pods: [get] does not grant pods/log: [get]. The subresource must be listed explicitly.

Auditing every SA in the cluster

A comprehensive audit walks every SA and reports its effective permissions:

#!/bin/bash
# audit-sas.sh — every SA's effective permissions

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
    KEY="$ns/$sa"
    echo "=== $KEY ==="
    kubectl auth can-i --list -n "$ns" \
      --as=system:serviceaccount:$ns:$sa 2>/dev/null
  done
done > sa-audit.txt

The output is the full audit. Comparing it to the expected surface per SA is a manual or automated step.

# Find SAs that can create RBAC objects (privilege escalation)
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 | grep -q yes; then
      ESCALATION+=("$ns/$sa")
    fi
    if kubectl auth can-i create clusterrolebindings \
       --as=system:serviceaccount:$ns:$sa \
       2>/dev/null | grep -q yes; then
      ESCALATION+=("$ns/$sa (cluster)")
    fi
  done
done

echo "PRIVILEGE ESCALATION SAs:"
printf '%s\n' "${ESCALATION[@]}"

Production failure modes

  1. Verification is not run before deploy. The pipeline runs kubectl apply and fails at admission. The fix is the verify script in CI/CD.
  2. Audit script is run quarterly, not on every change. A new Helm install adds an over-permissioned SA; the audit does not see it for three months. The fix is to run the audit in CI/CD.
  3. --list output is too long to read. The audit produces thousands of lines; the operator misses the over-permissioned SA. The fix is to encode the expected surface and diff against it.
  4. Impersonation is granted too widely. Every operator can --as=alice, allowing impersonation attacks. The fix is to restrict impersonate to a small set of admin SAs.

Cross-course references

  • The Observability course covers the audit log entries for SubjectAccessReview requests.
  • The Linux course covers the file permissions that Kubernetes RBAC does not enforce.

Quiz

Knowledge check · 4 questions

  1. Q1. Which command verifies that a SA can exec into a Pod in a namespace?

  2. Q2. `kubectl auth can-i --list` returns the *intersection* of every binding for an identity; if the SA is bound to two Roles, only the verbs that both Roles grant are returned.

  3. Q3. Your CI pipeline runs `verify-rbac.sh` and fails with `MISSING: create configmaps`. The SA `ci:ci-runner` is bound to a Role with `configmaps: [get, list, watch]`. The pipeline needs to create ConfigMaps. Why is the permission missing?

    The Role grants read-only verbs on ConfigMaps. The CI SA was set up for read-only operations (e.g., a deploy that does not create ConfigMaps). A new deployment pattern was added that creates ConfigMaps; the Role was not updated. The pipeline fails the verification step.

  4. Q4. Name three use cases for `kubectl auth can-i` in production operations.

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 flags (--as, --as-group, --list, --subresource) are the primitives; the patterns (verification, audit, debug) are the operations. A cluster whose RBAC is not verified is a cluster whose RBAC is not enforceable.