Kubernetes: Restrict a ServiceAccount with Namespace-Scoped RBAC without Breaking the Workload

Kubernetes ServiceAccount RBAC Restriction Tutorial

Kubernetes ServiceAccount RBAC Restriction Tutorial

This tutorial demonstrates how to restrict a ServiceAccount within a Kubernetes namespace using Role-Based Access Control (RBAC) without disrupting existing workloads. We’ll focus solely on Kubernetes concepts and YAML manifests.

Example 1: Initial Setup – The Basic ServiceAccount and Namespace

First, we’ll create a basic ServiceAccount and Namespace. This provides the foundation for our restrictions.

kubectl create namespace my-restricted-namespace
kubectl create serviceaccount my-serviceaccount --namespace my-restricted-namespace

Verify the creation:

kubectl get serviceaccount my-serviceaccount --namespace my-restricted-namespace
kubectl get namespace my-restricted-namespace

Output (example):

NAME          QRSTUVWXYZ(TIMESTAMP)
my-serviceaccount   0.01s
NAMESPACE        QRSTUVWXYZ(TIMESTAMP)
my-restricted-namespace   0.01s

Example 2: Initial Restriction – A Minimal RoleBinding

Now, we’ll create a simple RoleBinding to restrict the ServiceAccount to read pods within the namespace. This is a basic level of security.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: my-restricted-namespace
subjects:
- kind: ServiceAccount
  name: my-serviceaccount
  namespace: my-restricted-namespace
roleRef:
  kind: Role
  name: read-pods-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-pods-role
  namespace: my-restricted-namespace
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Apply the RoleBinding:

kubectl apply -f serviceaccount-rbac.yaml

Verify the RBAC configuration:

kubectl get rolebinding read-pods --namespace my-restricted-namespace
kubectl describe rolebinding read-pods --namespace my-restricted-namespace

You should see the RoleBinding and its rules. The `describe` output will show the subjects (ServiceAccount) and the role being granted.

Example 3: Incident – An Attempt to Access Resources Outside the Namespace

This scenario simulates an incident where a workload attempting to use `my-serviceaccount` tries to access resources outside `my-restricted-namespace`. This is a critical test of RBAC effectiveness.

Create a simple deployment (that uses the service account) to verify the restriction:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  namespace: my-restricted-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      serviceAccountName: my-serviceaccount
      containers:
      - name: test-container
        image: busybox:latest
        command: ["sleep", "3600"]

Apply the deployment:

kubectl apply -f test-deployment.yaml

Now, attempt to access resources outside `my-restricted-namespace` using the service account. For example, try to list pods in the `default` namespace:

kubectl get pods --namespace default

The command should fail with an authorization error: `Error from server (Forbidden): pods “…” not in the namespace “default”`, demonstrating the RBAC restriction is working.

Example 4: Correction – Refining the RoleBinding for Granular Control

The previous example used a broad `Role` to allow listing pods. To improve security, we’ll refine the RBAC to allow only reading pod names.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-names
  namespace: my-restricted-namespace
subjects:
- kind: ServiceAccount
  name: my-serviceaccount
  namespace: my-restricted-namespace
roleRef:
  kind: Role
  name: read-pods-names-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-pods-names-role
  namespace: my-restricted-namespace
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
  additionalHTTPHeaders:
    - name: "resourceVersion"
      required: false

Apply the corrected RoleBinding:

kubectl apply -f serviceaccount-rbac.yaml

Verify: `kubectl get pods –namespace my-restricted-namespace` should still succeed, but if you try to get a specific pod’s details (using `kubectl get pod -n my-restricted-namespace`), it will fail due to the refined Role.

Leave a Reply

Your email address will not be published. Required fields are marked *

We use cookies and similar technologies to enhance your experience on wobizdu.com, analyze site traffic, personalize content, and deliver relevant ads. Some cookies are essential for the site to function, while others help us improve performance and user experience. You may accept all cookies, decline optional ones, or customize your settings. Review our Privacy Policy to learn more.