Managing Roles Using RBAC Authorization

RBAC Authorization is one of the ways to assign roles to the users in a Kubernetes cluster. Learn more about this type of authorization in the official Kubernetes documentation.

We recommend that you first obtain the Service Account Token. Without using it, you’ll need to download kubeconfig after any role change.

Next, you need to enable the Pod Security Policy so that the security settings are applied to the cluster.

Example

A manifest for creating two namespaces and two users, either of which can only manage pods in their own namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: test-one
---
apiVersion: v1
kind: Namespace
metadata:
  name: test-two
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-one
  namespace: test-one
subjects:
- kind: ServiceAccount
  name: test-sa-one
  apiGroup: ""
roleRef:
  kind: Role
  name: pod-reader-one
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-two
  namespace: test-two
subjects:
- kind: ServiceAccount
  name: test-sa-two
  apiGroup: ""
roleRef:
  kind: Role
  name: pod-reader-two
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: test-one
  name: pod-reader-one
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: test-two
  name: pod-reader-two
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: test-one
  name: test-sa-one
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: test-two
  name: test-sa-two

After running a manifest, you need to manually add tokens to users so that they can log in without a password.

Creating tokens:

# kubectl get secret $(kubectl get serviceaccount test-sa-one -o jsonpath='{.secrets[0].name}' --namespace test-one) -o jsonpath='{.data.token}' --namespace test-one | base64 -d
<long and secure token for test-sa-one>


# kubectl get secret $(kubectl get serviceaccount test-sa-two -o jsonpath='{.secrets[0].name}' --namespace test-two) -o jsonpath='{.data.token}' --namespace test-two | base64 -d
<long and secure token for test-sa-two>

Adding tokens to users in the kubeconfig.yaml file:

users:
...
- name: test-sa-one
  user:
    token: <long and secure token test-sa-one>
- name: test-sa-two
  user:
    token: <long and secure token test-sa-two>
...

Checking the distribution of roles:

# kubectl config set-context --current --user=test-sa-two
Context "admin@kubernetes" modified.


# kubectl get pods --namespace test-two
No resources found in test-two namespace.


# kubectl get pods --namespace test-one
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:test-two:test-sa-two" cannot list resource "pods" in API group "" in the namespace "test-one"

________

# kubectl config set-context --current --user=test-sa-one
Context "admin@kubernetes" modified.


# kubectl get pods --namespace test-two
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:test-one:test-sa-one" cannot list resource "pods" in API group "" in the namespace "test-two"


# kubectl get pods --namespace test-one
No resources found in test-one namespace.

The test-sa-two user now is provided with access to pods in the test-two namespace and does not have access in the test-one namespace. For the test-sa-one user, quite the opposite.