Kubernetes Access Control: Implementing RBAC with Custom kubeconfig Files
In multi-tenant Kubernetes environments, proper access control becomes crucial. Administrators often need to assign isolated namespaces to different users while restricting their permissions to specific operations. For instance, preventing ceertain users from executing destructive commands like kubectl delete node is essential for cluster security.
This becomes particularly relevant when tools like VS Code need to connect to pods using local kubeconfig files. Creating minimal-permission kubeconfig files for different tenants ensures secure access without exposing unnecessary cluster controls.
RBAC Configuraton
Understanding RBAC in Kubernetes
RBAC (Role-Based Access Control) in Kubernetes provides a granular mechanism for managing API access permissions. It operates through four main components:
- Role: Defines permission sets for resources within a specific namespace
- RoleBinding: Associates roles with users, groups, or ServiceAccounts
- ClusterRole: Similar to Role but operates across the entire cluster
- ClusterRoleBinding: Binds ClusterRoles to entities at cluster scope
Creating RBAC Resources
Let's configure RBAC for a user named developer1:
1. ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: developer1-sa
namespace: production
2. Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer1-role
namespace: production
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete"]
3. RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer1-binding
namespace: production
subjects:
- kind: ServiceAccount
name: developer1-sa
namespace: production
roleRef:
kind: Role
name: developer1-role
apiGroup: rbac.authorization.k8s.io
4. Secret (Kubernetes 1.24+):
apiVersion: v1
kind: Secret
metadata:
name: developer1-token
annotations:
kubernetes.io/service-account.name: "developer1-sa"
type: kubernetes.io/service-account-token
After applying these configurations, the Secret will contain the necessary CA certificate and authentication token.
Kubeconfig Configuration
Kubeconfig Structure
The kubeconfig file organizes access information through three main sections:
- clusters: Contains cluster connection details and CA certificates
- users: Stores authentication credentials for various identities
- contexts: Links users to clusters and specifies default namespaces
Building Custom Kubeconfig
Extract the token and CA certificate from the created Secret:
# Get the raw token
kubectl get secret developer1-token -o jsonpath='{.data.token}' | base64 -d
# Get the CA certificate (already base64 encoded)
kubectl get secret developer1-token -o jsonpath='{.data.ca\.crt}'
Create a dedicated kubeconfig file:
apiVersion: v1
kind: Config
clusters:
- name: production-cluster
cluster:
server: https://your-cluster-api-server:6443
certificate-authority-data: LS0tLS1CRUdJTi... (base64 CA cert)
users:
- name: developer1
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6... (raw token)
contexts:
- name: developer1-context
context:
cluster: production-cluster
namespace: production
user: developer1
current-context: developer1-context
Testing Access Controls
To tesst the new configuration, either replace the default kubeconfig temporarily or merge using the KUBECONFIG environment variable:
# macOS/Linux
export KUBECONFIG=$HOME/.kube/config:$HOME/custom-config
# Windows
set KUBECONFIG=%USERPROFILE%\.kube\config;%USERPROFILE%\custom-config
Switch contexts using kubectl:
# View available contexts
kubectl config get-contexts
# Switch to the new context
kubectl config use-context developer1-context
# Test permissions (should succeed)
kubectl get pods
# Test restricted operations (should fail)
kubectl get nodes
The RBAC rules will now enforce the defined permissions, allowing pod operations while restricting cluster-wide access.