How to Configure Kubernetes API Access Control
Set up secure API server access with authentication and authorization. Configure RBAC, API groups, and audit logging for cluster security.
π‘ Quick Answer: Kubernetes API security uses three layers: Authentication (who you areβX.509 certs, OIDC, ServiceAccount tokens), Authorization (what you can doβRBAC, ABAC, webhooks), and Admission Control (policy enforcement). Configure RBAC with
Role/ClusterRoleand bind viaRoleBinding/ClusterRoleBinding.Key command:
kubectl auth can-i --list --as=system:serviceaccount:default:mysato verify permissions.Gotcha: Enable audit logging (
--audit-log-path) to track API access and debug permission issues.
Secure Kubernetes API access through authentication, authorization, and audit logging. Configure RBAC policies, manage API groups, and implement least-privilege access.
Authentication Methods
# Kubernetes supports multiple authentication strategies:
# 1. X.509 Client Certificates
# 2. Bearer Tokens (ServiceAccount, OIDC, Webhook)
# 3. Basic Auth (deprecated)
# 4. OpenID Connect (OIDC)
# 5. Authentication Proxy
# Check current authentication
kubectl auth whoami # Kubernetes 1.27+
# Or older method
kubectl config view --minify -o jsonpath='{.contexts[0].context.user}'X.509 Certificate Auth
# Generate client certificate
openssl genrsa -out developer.key 2048
openssl req -new -key developer.key -out developer.csr \
-subj "/CN=developer/O=dev-team"
# Sign with cluster CA (requires cluster admin)
openssl x509 -req -in developer.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out developer.crt -days 365
# Add to kubeconfig
kubectl config set-credentials developer \
--client-certificate=developer.crt \
--client-key=developer.key
kubectl config set-context developer-context \
--cluster=my-cluster \
--user=developerServiceAccount Token Auth
# Create ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-user
namespace: default
---
# Create long-lived token (if needed)
apiVersion: v1
kind: Secret
metadata:
name: ci-user-token
annotations:
kubernetes.io/service-account.name: ci-user
type: kubernetes.io/service-account-token# Get token
kubectl get secret ci-user-token -o jsonpath='{.data.token}' | base64 -d
# Or create short-lived token (preferred)
kubectl create token ci-user --duration=24hRBAC Components
# Role: Namespace-scoped permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-manager
namespace: development
rules:
- apiGroups: [""] # Core API group
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: [""]
resources: ["pods/log", "pods/exec"]
verbs: ["get", "create"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
---
# RoleBinding: Grants Role to subjects
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-manager-binding
namespace: development
subjects:
- kind: User
name: developer
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
name: ci-user
namespace: default
roleRef:
kind: Role
name: pod-manager
apiGroup: rbac.authorization.k8s.ioClusterRole and ClusterRoleBinding
# ClusterRole: Cluster-wide permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-reader
rules:
- apiGroups: [""]
resources: ["nodes", "namespaces", "persistentvolumes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-reader-binding
subjects:
- kind: Group
name: readonly-users
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-reader
apiGroup: rbac.authorization.k8s.ioAPI Groups and Resources
# List all API groups
kubectl api-resources --output=wide
# Common API groups:
# "" (core) - pods, services, configmaps, secrets
# apps - deployments, statefulsets, daemonsets
# batch - jobs, cronjobs
# networking.k8s.io - ingresses, networkpolicies
# rbac.authorization.k8s.io - roles, rolebindings
# List resources in group
kubectl api-resources --api-group=apps
# Get API group versions
kubectl api-versions | grep appsResource Names and Subresources
# Restrict to specific resources by name
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: config-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config", "env-config"] # Only these
verbs: ["get"]
---
# Subresources (pods/log, pods/exec, etc.)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-logs
rules:
- apiGroups: [""]
resources: ["pods/log"] # Subresource
verbs: ["get"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"] # Exec requires create verbRBAC Verbs
# Available verbs:
# get - Read single resource
# list - List resources
# watch - Watch for changes
# create - Create resources
# update - Update existing resources
# patch - Patch resources
# delete - Delete single resource
# deletecollection - Delete multiple resources
# Common verb combinations:
rules:
# Read-only
- verbs: ["get", "list", "watch"]
# Full CRUD
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Write-only (rare)
- verbs: ["create", "update", "delete"]Aggregated ClusterRoles
# Base ClusterRole with label
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-rules
labels:
rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: ["monitoring.coreos.com"]
resources: ["prometheusrules", "servicemonitors"]
verbs: ["get", "list", "watch"]
---
# Aggregating ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-admin
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # Rules are aggregated from matching ClusterRolesTest Permissions
# Check if you can perform action
kubectl auth can-i create pods
kubectl auth can-i delete deployments -n production
# Check as another user
kubectl auth can-i get pods --as=developer
kubectl auth can-i get pods --as=system:serviceaccount:default:ci-user
# List all permissions
kubectl auth can-i --list
kubectl auth can-i --list --as=developer -n development
# Check in specific namespace
kubectl auth can-i create deployments -n productionAudit Logging
# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Don't log read-only requests to certain resources
- level: None
resources:
- group: ""
resources: ["events", "nodes/status"]
verbs: ["get", "list", "watch"]
# Log auth failures
- level: Metadata
users: ["system:anonymous"]
# Log secrets access at metadata level (no body)
- level: Metadata
resources:
- group: ""
resources: ["secrets"]
# Log everything else at request level
- level: Request
omitStages:
- RequestReceivedCommon RBAC Patterns
# Developer access
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"] # Read only secrets
---
# CI/CD Pipeline
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ci-deployer
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "create", "update"]
---
# Monitoring
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
rules:
- apiGroups: [""]
resources: ["nodes", "pods", "services", "endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["nodes/metrics", "pods/metrics"]
verbs: ["get"]Debug RBAC Issues
# Check why access denied
kubectl describe rolebinding -n namespace
kubectl describe clusterrolebinding
# View role permissions
kubectl describe role pod-manager -n development
kubectl describe clusterrole cluster-reader
# Check subject's bindings
kubectl get rolebindings,clusterrolebindings -A \
-o jsonpath='{range .items[?(@.subjects[*].name=="developer")]}{.metadata.name}{"\n"}{end}'Summary
Kubernetes API access control uses authentication (who you are) and authorization (what you can do). Configure RBAC with Roles/ClusterRoles (define permissions) and RoleBindings/ClusterRoleBindings (grant to subjects). Use least-privilege principles - grant minimum necessary permissions. Test access with kubectl auth can-i. Enable audit logging to track API access. Common patterns include read-only cluster access, namespace-scoped developer access, and CI/CD deployment permissions.
π Go Further with Kubernetes Recipes
Love this recipe? Thereβs so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.
Inside the book, youβll master:
- β Production-ready deployment strategies
- β Advanced networking and security patterns
- β Observability, monitoring, and troubleshooting
- β Real-world best practices from industry experts
βThe practical, recipe-based approach made complex Kubernetes concepts finally click for me.β
π Get Your Copy Now β Start building production-grade Kubernetes skills today!

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
