Least Privilege
The principle of least privilege means granting only the minimum permissions necessary for a user or application to perform its function. In Kubernetes, this reduces the attack surface and limits the damage from compromised accounts or applications.
Why Least Privilege Matters
Imagine giving every employee a master key to your entire building. If one key is lost or stolen, the entire building is at risk. Least privilege is like giving each employee a key only to the rooms they actually need.
In Kubernetes terms:
- A compromised application with excessive permissions can affect other namespaces or cluster components
- Accidental mistakes have limited scope when permissions are restricted
- Compliance requirements often mandate least privilege
- Security audits are easier when permissions are minimal and documented
How to Implement Least Privilege
1. Start with No Permissions
Begin by creating users and ServiceAccounts with no permissions, then add only what’s needed:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: production
This ServiceAccount has zero permissions until you create a RoleBinding.
2. Grant Specific Permissions
Instead of using broad roles like admin or edit, create custom roles with exact permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-specific
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"] # Only this specific ConfigMap
verbs: ["get"]
- apiGroups: ["apps"]
resources: ["deployments"]
resourceNames: ["my-app"] # Only this specific Deployment
verbs: ["get", "patch"]
3. Use Namespace Isolation
Limit permissions to specific namespaces:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-access
namespace: development # Only this namespace
subjects:
- kind: User
name: developer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
Auditing Permissions
Check Current Permissions
Use kubectl auth can-i to see what a user or ServiceAccount can do:
# List all permissions for a ServiceAccount
kubectl auth can-i --list \
--as=system:serviceaccount:production:my-app \
--namespace=production
# Test specific permission
kubectl auth can-i create pods \
--as=system:serviceaccount:production:my-app \
--namespace=production
Analyze Role Bindings
Find all bindings for a user or ServiceAccount:
# Find all RoleBindings for a user
kubectl get rolebindings,clusterrolebindings --all-namespaces \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .subjects[*]}{.kind}{"/"}{.name}{"\n"}{end}{end}' \
| grep "User/alice"
# Find all bindings for a ServiceAccount
kubectl get rolebindings --all-namespaces \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .subjects[*]}{.kind}{"/"}{.name}{"\n"}{end}{end}' \
| grep "ServiceAccount/my-app"
Tools for Permission Analysis
kubectl-who-can
A plugin that shows who can perform specific actions:
kubectl who-can create pods --namespace=production
kubectl who-can delete deployments --namespace=production
rbac-lookup
Lists all permissions for a user or ServiceAccount:
rbac-lookup alice
rbac-lookup system:serviceaccount:production:my-app
rakkess
Shows access matrix for resources:
rakkess --namespace production
Common Mistakes to Avoid
1. Using Cluster-admin Unnecessarily
❌ Bad: Giving a developer cluster-admin to “make things easier”
✅ Good: Create a namespace-scoped role with only needed permissions
2. Wildcard Verbs
❌ Bad: Using verbs: ["*"] when only read access is needed
✅ Good: Specify exact verbs: verbs: ["get", "list", "watch"]
3. ClusterRole for Namespace Resources
❌ Bad: Using ClusterRoleBinding for namespace-scoped resources
✅ Good: Use RoleBinding with a Role or ClusterRole
4. Overly Broad Resource Access
❌ Bad: resources: ["*"] when only specific resources are needed
✅ Good: List specific resources: resources: ["pods", "services"]
Permission Patterns
Read-Only Access
For developers who need to debug but not modify:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: read-only
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
Application Permissions
For an application that only needs to read its own ConfigMap:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"]
verbs: ["get"]
CI/CD Permissions
For a CI/CD system that deploys to specific namespaces:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: cicd-deployer
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
Regular Audits
Schedule regular permission reviews:
- Monthly - Review new RoleBindings and ClusterRoleBindings
- Quarterly - Audit all permissions for unused or excessive access
- Annually - Comprehensive security review with compliance teams
Audit Checklist
- Are there any ClusterRoleBindings that should be RoleBindings?
- Do any roles use wildcard verbs or resources unnecessarily?
- Are ServiceAccounts using minimal permissions?
- Can any permissions be scoped to specific resource names?
- Are there unused roles or bindings that can be removed?
- Do developers have more permissions than needed?
Remediation Steps
When you find excessive permissions:
- Document the current state - Record what permissions exist and why
- Create a minimal role - Define the exact permissions needed
- Test in a non-production environment - Verify the new permissions work
- Update the binding - Switch to the new minimal role
- Monitor for issues - Watch for permission denied errors
- Remove old role - Once confirmed working, delete the old role
See Also
- RBAC Overview - Introduction to RBAC
- Roles & Bindings - Understanding roles and bindings
- Policy Enforcement - Automated policy enforcement
- Audit & Compliance - Auditing and compliance