Right, so you’ve got your RBAC all set up. Roles, bindings, the whole nine yards. It looks good on paper. But how do you know it’s doing what you think it’s doing? You don’t just deploy this stuff and hope for the best. You poke it with a stick. And the best stick for poking RBAC is kubectl auth can-i.

This command is your RBAC truth-teller. It cuts through the YAML and tells you, for a specific user or service account, whether a specific action is permitted. It’s the difference between assuming your new intern can’t delete a production namespace and knowing it.

The basic syntax is brain-dead simple. You’re just asking a question.

kubectl auth can-i create pod

Which will return a simple yes or no. By default, it’s asking about your current user credentials, as determined by your kubeconfig context. This is incredibly useful for a quick sanity check. “Wait, can I even do that?”.

Checking Permissions for Other Users and ServiceAccounts

Here’s where it gets powerful. You’re not just limited to checking your own perms. The real value is in impersonating other entities, especially those pesky service accounts your apps run under. This is how you debug that “Why can’t my app create a ConfigMap?!” ticket without guesswork.

Use the --as flag to impersonate a user and the --as-group flag for groups.

# Can the user 'jane' delete deployments in the 'logging' namespace?
kubectl auth can-i delete deployments --namespace logging --as jane

# Can someone in the 'dev-team' group create namespaces?
kubectl auth can-i create namespace --as-group dev-team

But most importantly, you’ll use it for ServiceAccounts. The syntax is a bit wonky because you have to provide the full path to the service account, but it’s a lifesaver.

# Can the 'api-service' service account in the 'app' namespace list secrets in its own namespace?
kubectl auth can-i list secrets --namespace app --as system:serviceaccount:app:api-service

Let’s be honest, the system:serviceaccount:<namespace>:<serviceaccountname> thing is a mouthful. The designers clearly weren’t thinking about our typing stamina when they came up with that. But it’s consistent, and once you muscle-memory it, you’re golden.

Unleashing the Verbosity: –verbose

A simple yes or no is good, but it’s not terribly informative. Why is it yes? Which RoleBinding granted this permission? This is where the --verbose (-v) flag earns its keep. It tells you exactly which rule allowed or denied the request.

kubectl auth can-i create deployment --namespace test --as system:serviceaccount:test:ci-bot -v

The output might show you:

yes - because of cluster role "deployer"

Or it might give you a heartbreaking:

no

The verbose flag doesn’t currently give you a reason for a no, which is a bit of a design oversight if you ask me. It’s like a security guard just saying “nope” without explanation. For denials, you’ll have to start digging through bindings and roles the old-fashioned way.

The Superuser Pitfall and the –all-namespaces Flag

Here’s a classic “oh crap” moment waiting to happen. You run a check from your admin context and forget a crucial detail.

# Running this as cluster-admin... from your laptop
kubectl auth can-i "*" "*"

This will, unsurprisingly, return yes. Because you’re basically God in the cluster. This is useless. Always be mindful of the context you’re in and use --as to impersonate the actual identity you’re trying to test. This command doesn’t lie, but it will happily answer the question you asked, not the question you meant to ask.

To check permissions cluster-wide, not just in a default or specified namespace, use the --all-namespaces flag. This is critical for non-namespaced resources (like Nodes, PersistentVolumes) and ClusterRoles.

# Can the 'cluster-viewer' service account get Nodes across the entire cluster?
kubectl auth can-i get nodes --all-namespaces --as system:serviceaccount:monitoring:cluster-viewer

Best Practices and Scripting This Beast

Don’t just use this command reactively when things break. Wire it into your CI/CD pipeline and GitOps processes. Before you deploy a new service account and set of roles, write a script that uses kubectl auth can-i to validate the permissions before the pod ever starts. This is how you shift-left your security posture.

You can use it in scripts by checking the exit code. A yes returns an exit code of 0 (success), and a no returns 1. This is perfect for automation.

#!/bin/bash
if kubectl auth can-i create secret --as system:serviceaccount:app:api-service &>/dev/null; then
    echo "✅ Service account has permission to create secrets."
else
    echo "❌ Permission DENIED. Fix your RBAC."
    exit 1
fi

In the end, kubectl auth can-i is the most direct line you have to the Kubernetes authorization engine. It removes ambiguity. Use it relentlessly, script it, and never deploy a service account without first asking it what it can actually do. Your future, less-stressed self will thank you for it.