Shashikant shah

Friday, 21 February 2025

RBAC Authorization and Service Account in Kubernetes.

 

Authentication :-

Kubernetes supports multiple authentication mechanisms to verify the identity of users and service accounts when interacting with the cluster.

Authentication Methods in Kubernetes:

Authentication Type

Description

Use Case

X.509 Client Certificates

Uses TLS certificates to authenticate users.

Secure authentication for cluster admins & automation.

Bearer Tokens (Service Accounts)

Uses a token for API authentication.

Pod-to-API authentication, service accounts.

Static Password File (Basic Auth) [Deprecated]

Uses a static password file for authentication.

Not recommended, removed in v1.19+.

Static Token File (Token Auth) [Deprecated]

Uses a static file with predefined tokens.

Not recommended, removed in v1.22+.

OpenID Connect (OIDC)

Uses external identity providers like Google, Okta, or Keycloak.

Enterprise-level authentication, SSO.

Webhook Token Authentication

Uses an external webhook server for authentication.

Custom authentication integration.

Keystone Authentication

Uses OpenStack Keystone for authentication.

Kubernetes in OpenStack environments.


Authorization :-

Kubernetes supports multiple authorization modes, which can be enabled via the API server (kube-apiserver) using the --authorization-mode flag.

The main modes are:

ABAC (Attribute-Based Access Control)

Uses policy files to define permissions.

RBAC (Role-Based Access Control)

Grants access based on roles and bindings.

Webhook Authorization

Calls an external service to decide access.

Node Authorization

Special authorization for kubelets to access required resources.

AlwaysAllow

Grants all requests (not recommended for production).

AlwaysDeny

Blocks all requests (used for testing security policies).

 1.ABAC (Attribute-Based Access Control)(Policy): Less common, based on attributes like user role, request type, and other metadata.

The policy will be assigned to single user.

2.RBAC (Role-Based Access Control): The most commonly used model in Kubernetes. Users and services are assigned roles (e.g., admin, developer, viewer), and each role has specific permissions (e.g., get, list, create, delete).

RBAC is a Action based funcation.

Users à actions à resources

Four object for rbac :-

i). Role.

ii). Rolebinding.

iii). ClusterRole.

iv). ClusterRoleBinding.

i). Role :-



A Role is a Kubernetes resource that defines what actions (verbs) can be performed on which resources in a namespace.

 ##

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

  name: pod-reader    # role Name

  namespace: default   # Applies only to "default" namespace

rules:

- apiGroups: [""]

  resources: ["pods"]         # resource name

  verbs: ["get", "list", "watch"]   #Permission

 

Namespaced Resources: Limited to a specific namespace.

Resource

Description

Pods

Manage Pods.

Services

Manage Services.

Configmaps

Manage ConfigMaps.

Secrets

Manage Secrets (usually restricted).

persistentvolumeclaims

Manage PVCs (Persistent Volume Claims).

Deployments

Manage Deployments.

Replicasets

Manage ReplicaSets.

Statefulsets

Manage StatefulSets.

Daemonsets

Manage DaemonSets.

Jobs

Manage Jobs.

Cronjobs

Manage CronJobs.

Ingresses

Manage Ingress resources.

Events

Read/write Kubernetes events.

Endpoints

Manage Endpoints.

Resourcequotas

Manage Resource Quotas.

Limitranges

Manage Limit Ranges.

Verbs in Kubernetes RBAC:-

Verb

Description

Get

Read a specific resource (e.g., kubectl get pod mypod).

List

List all resources of that type in the namespace or cluster.

Watch

Watch for changes to resources (used for monitoring).

Create

Create new resources.

Update

Modify existing resources (without changing metadata like name).

Patch

Apply a partial update (useful for modifying a single field).

Delete

Delete a resource.

deletecollection

Delete multiple resources at once.

Impersonate

Act as another user or service account.

 

* → Grants all permissions on the resource.

verbs: ["*"]

 

ii). Rolebinding :- Binds a Role to a user, group, or service account within a specific namespace.

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

  name: pod-reader-binding   # RoleBinding Name

  namespace: default                # permission apply for namespace

subjects:

- kind: User

  name: john  # The user receiving the role

  apiGroup: rbac.authorization.k8s.io

roleRef:

  kind: Role

  name: pod-reader  # Referencing the Role name

  apiGroup: rbac.authorization.k8s.io

 

RoleBinding for group.

subjects:

- kind: Group

  name: dev-team

  apiGroup: rbac.authorization.k8s.io

RoleBinding for ServiceAccount.

subjects:

- kind: ServiceAccount

  name: my-app

  namespace: default

 

iii). ClusterRole.

A ClusterRole in Kubernetes is a cluster-wide Role that grants permissions to resources across all namespaces or cluster-wide resources like Nodes, PersistentVolumes, and Namespaces.

##### 

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: cluster-pod-reader

rules:

- apiGroups: [""]

  resources: ["pods"]  # Grants permissions for Pods.

  verbs: ["get", "list", "watch"]  # Allows read-only actions.

 

Since this is a ClusterRole, it applies to all namespaces.

Cluster-wide Resources → Available across the whole cluster.


iv). ClusterRoleBinding :- Binds a ClusterRole to a user, group, or service account at the cluster level k8s.

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: cluster-pod-reader-binding

subjects:

- kind: User

  name: john  # Assigning permissions to user "john"

  apiGroup: rbac.authorization.k8s.io

roleRef:

  kind: ClusterRole

  name: cluster-pod-reader  # Referencing the ClusterRole

  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding for group.

subjects:

- kind: Group

  name: test-team

  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding for ServiceAccount.

subjects:

- kind: ServiceAccount

  name: ops-team

  namespace: default

 

3.Webhook Authorization:

A custom method where an external service decides if the user is authorized based on its own rules.

i) A user makes a request to the Kubernetes API Server.

ii) If RBAC and other authorization methods don't handle the request, it is sent to the Webhook Authorization server.

iii)The webhook server checks the request and approves or denies it.

iv)Kubernetes allows or denies the request based on the webhook response.


4.Node Authorization:

Node Authorization is a special authorization mode in Kubernetes that controls what actions kubelets (worker nodes) can perform on the API server. It is specifically designed for nodes to limit their access to only the resources they need.

How Node Authorization Works

1.     A kubelet running on Node-1 makes a request to the Kubernetes API Server.

2.     The API Server checks if Node Authorization allows it.

3.     If approved, the kubelet gets access to only its assigned resources.

4.     If denied, the request is rejected.

kube-apiserver --authorization-mode=Node,RBAC

Nodes can only access their own resources (ConfigMaps).

# vim file.yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: node-configmap-reader

rules:

- apiGroups: [""]

  resources: ["configmaps"]

  verbs: ["get", "list", "watch"]

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: node-configmap-binding

subjects:

- kind: Group

  name: system:nodes  # Applies to all nodes

  apiGroup: rbac.authorization.k8s.io

roleRef:

  kind: ClusterRole

  name: node-configmap-reader

  apiGroup: rbac.authorization.k8s.io

 

Admission Control in Kubernetes:

Admission Control in Kubernetes is a security and validation layer that runs after authentication and authorization.

1.Act as gatekeeper and process Kubernetes API server request before persists in ETCD.

2.Admin Controllers are compiled with Kube API Server binaries.

3.The Admission Control process proceeds in 2 phases.

1st phases : mutating admission controllers will run.

2nd  phases : validating admission controllers will run.

4.If any Controller phase rejects, entire request will be rejected with error.

5.Admission Controllers work on requests to create, delete, modify objectes.

6.No work for Read Objects.

How Admission Control Works.

1.     User or service sends a request to the Kubernetes API Server.

2.     Kubernetes authenticates the request (e.g., via tokens, certificates).

3.     Kubernetes checks authorization (RBAC, ABAC, or Webhook).

4.     If authorized, the request is sent to admission controllers for validation or mutation.

5.     If the request passes, it is stored in etcd and applied to the cluster.

If the admission controller rejects the request, Kubernetes does not execute it.


To create a read-only user called John for the namespace finance, follow these steps:

1.Created a private key and certificate for John.
2.Signed John’s certificate with the Kubernetes CA.
3.Configured John's kubeconfig for authentication.
4.Created a Role to allow John to list pods in finance.
5.Bound the Role to John using a RoleBinding.
6.Verified that John can only list pods.
 





Create a namespace finance.
# kubectl create ns finance

# kubectl get ns
NAME              STATUS   AGE
default           Active   22h
finance           Active   26s
kube-node-lease   Active   22h
kube-public       Active   22h
kube-system       Active   22h
 

1. Generate a Private Key for John.
# openssl genrsa -out john.key 2048
 
2. Generate a Certificate Signing Request (CSR).
# openssl req -out john.csr -key john.key -subj "/CN=john/O=finance" -new
CN=john → Common Name (John's username in Kubernetes).
O=finance → Organization (maps to Kubernetes groups/namespace).
 
3. Copy the Kubernetes CA Certificate and Key.
# cp -rvf /etc/kubernetes/pki/ca.{crt,key} .
 
4. Sign John’s CSR to Generate a Certificate.
# openssl x509 -req -in john.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out john.crt -days 365
 
5. View Kubernetes Configuration.
# kubectl config view
 
6. Set Up the Kubernetes Cluster for John.
# kubectl --kubeconfig john.kubeconfig config set-cluster kubernetes --server https://192.168.56.132:6443 --certificate-authority=ca.crt
# kubectl --kubeconfig=john.kubeconfig config view






7. Set Up John’s Credentials.
# kubectl --kubeconfig john.kubeconfig config set-credentials john --client-certificate /root/temp/john.crt --client-key /root/temp/john.key
# kubectl --kubeconfig=john.kubeconfig config view










8.Set John’s Kubernetes Context.

# kubectl --kubeconfig john.kubeconfig config set-context john-kubernetes --cluster kubernetes --namespace finance --user john

# kubectl --kubeconfig=john.kubeconfig config view

9. Verify the kubeconfig file.

# vim  john.kubeconfig

name: john-kubernetes

current-context: "john-kubernetes"

10. Verify John's Access to Pods.

# kubectl --kubeconfig john.kubeconfig get pods

Note: user "john" does not have permission to list pods in the "finance" namespace.

11. Create a Role for John.

# kubectl create role --help

# kubectl create role  finance-pod-reader  --verb=get,list,watch --resource=pods --namespace finance

                    OR

# vim finance-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: finance-pod-reader
  namespace: finance
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
# kubectl  apply -f  finance-role.yaml

12. Verify the Role.
# kubectl get role -n finance





# kubectl get role -n finance -o yaml

                             OR

# kubectl describe role -n finance








Field

Explanation

Resources

Specifies the resource this Role applies to. Here, it applies to pods.

Non-Resource URLs

Empty ([]), meaning this Role does not grant permissions on API endpoints (e.g., /metrics, /healthz).

Resource Names

Empty ([]), meaning it applies to all pods in the finance namespace, not just specific ones.

Verbs

The actions the user is allowed to perform on the pods resource. Here, get, list, and watch.


13. Bind the Role to John.
# kubectl create rolebinding john-finance-rolebinding --role=finance-pod-reader  --user=john --namespace finance

              OR

# vim john-finance-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: john-finance-rolebinding
  namespace: finance
subjects:
  - kind: User
    name: john  # Ensure this matches the username in john.kubeconfig
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: finance-pod-reader  # Ensure this Role exists in the finance namespace
  apiGroup: rbac.authorization.k8s.io 
# kubectl apply -f john-finance-rolebinding.yaml

 

14. Verify the RoleBinding.

# kubectl get rolebinding -n finance





# kubectl get rolebinding -n finance  -o yaml

# kubectl describe rolebinding -n finance






15. Test John's Access.

# kubectl --kubeconfig john.kubeconfig get pods (only access pods in finance namespace).





# kubectl --kubeconfig john.kubeconfig get sts

Error from server (Forbidden): statefulsets.apps is forbidden: User "john" cannot list resource "statefulsets" in API group "apps" in the namespace "finance




How to access other machine use john user :-

# useradd jk

# sudo su - jk

# mkdir -p /home/jk/.kube

# copy file john.crt  john.key ca.crt and paste to  /home/jk/.kube

# chown -R jk:jk /home/jk/.kube/

# export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config:$HOME/.kube/john.kubeconfig

OR

# vim /home​/​jk/.profile and .bashrc

export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config:$HOME/.kube/john.kubeconfig

# kubectl get deploy





To create a read-only group called dev_team for the namespace finance-team.




1. Generate a Private Key for the User.

# openssl genrsa -out ravi.key 2048

2. Create a Certificate Signing Request (CSR).

# openssl req -new -key  ravi.key  -out ravi.csr -subj "/CN=ravi/O=dev_team" 

i) CN=ravi → This is the username in Kubernetes.

ii)  O=dev_team → This is the group the user belongs to.

3. Copy the Kubernetes CA Certificate and Key.
# cp -rvf /etc/kubernetes/pki/ca.{crt,key} .

4.Sign the Certificate with the Kubernetes CA.

# openssl x509 -req -in ravi.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ravi.crt -days 365

5.Verify the User’s Group.
# openssl x509 -in  ravi.crt -text -noout | grep Subject








6. Set Up the Kubernetes Cluster for ravi.

# kubectl  --kubeconfig ravi.kubeconfig config set-cluster kubernetes --server https://192.168.56.132:6443 --certificate-authority=ca.crt

# kubectl --kubeconfig=ravi.kubeconfig config view

7. Set Up ravi Credentials.

# kubectl --kubeconfig  rav.kubeconfig config set-credentials ravi --client-certificate /root/temp/ravi.crt --client-key /root/temp/ravi.key

# kubectl --kubeconfig=ravi.kubeconfig config view

8.Create a User’s Kubeconfig File.

# kubectl config set-credentials ravi \

  --client-certificate=ravi.crt \

  --client-key=ravi.key

9.Set ravi Kubernetes Context.

# kubectl --kubeconfig ravi.kubeconfig config set-context ravi-kubernetes --cluster kubernetes --namespace finance-team  --user ravi

# kubectl --kubeconfig=ravi.kubeconfig config view

10. Verify the kubeconfig file.

# vim  ravi.kubeconfig

name: ravi-kubernetes

current-context: "ravi-kubernetes"

11. Verify ravi Access to Pods.

# kubectl --kubeconfig ravi.kubeconfig get pods

Note: user "ravi" does not have permission to list pods in the "finance-team" namespace.

12.Create a Role for Read-Only Access.

# kubectl create role dev-team-readonly  --verb=get,list,watch  --resource=*  --namespace finance-team

13.Bind the Role to the Group dev_team.

# kubectl create rolebinding dev-team-rolebinding  --role=dev-team-readonly  --group=dev_team  --namespace finance-team

14.Verify Role and RoleBinding.

# kubectl get role -n finance-team

# kubectl describe role dev-team-readonly -n finance-team 









# kubectl get rolebinding -n finance-team
# kubectl describe rolebinding dev-team-rolebinding -n finance-team









15.Test Access.

# kubectl --kubeconfig ravi.kubeconfig get pods -n finance-team

Since this is read-only, they cannot create or delete resources in finance-team. 

Note :-

Ensure Users are in the dev_team Group:

To allow users to authenticate as part of the dev_team group, their client certificates (or identity provider settings) must include the group information.

# openssl req -new -key user.key -out user.csr -subj "/CN=username/O=dev_team"

i) The CN (Common Name) is the username.

ii)  The O (Organization) is dev_team, which maps the user to this group in Kubernetes.


To create a read-only user (kustav) with ClusterRole & ClusterRoleBinding in Kubernetes.

User

Permssion

RBAC

kustav

read-only

ClsuterRole/ClusterRolebinding

 

1️.Generate SSL Certificate for User

openssl genrsa -out kustav.key 2048

openssl req -new -key kustav.key -out kustav.csr -subj "/CN=kustav/O=read-only"

cp -rvf /etc/kubernetes/pki/ca.{crt,key} .

openssl x509 -req -in kustav.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kustav.crt -days 365

  • Generates a private key (kustav.key).
  • Creates a CSR (kustav.csr) for the user.
  • Signs it with the Kubernetes CA (ca.crt & ca.key) to issue a certificate (kustav.crt).

2️.Configure kustav.kubeconfig

# kubectl --kubeconfig=kustav.kubeconfig config set-cluster kubernetes --server=https://<KUBE_API_SERVER>:6443 --certificate-authority=ca.crt

# kubectl --kubeconfig=kustav.kubeconfig config set-credentials kustav --client-certificate=kustav.crt --client-key=kustav.key

# kubectl --kubeconfig=kustav.kubeconfig config set-context kustav-context --cluster=kubernetes --user=kustav

# kubectl --kubeconfig=kustav.kubeconfig config use-context kustav-context

  • Sets up a kubeconfig file for kustav to use.

3️.Create ClusterRole with Read-Only Access

# kubectl create clusterrole read-only-role --verb=get,list,watch --resource=pods,services,deployments,nodes,configmaps

  • Grants read-only access to important resources (get, list, watch). 

4️.Bind Role to User (ClusterRoleBinding)

# kubectl create clusterrolebinding kustav-readonly-binding --clusterrole=read-only-role --user=kustav

  • Binds read-only-role to kustav, allowing read-only access across the entire cluster.

5️.Verify Permissions

kubectl --kubeconfig=kustav.kubeconfig auth can-i list pods --all-namespaces

kubectl --kubeconfig=kustav.kubeconfig get pods -A

  • Checks if kustav has list permissions.
  • Lists all pods in all namespaces.

Kubernetes Service Account with RBAC

If you want to create a Service Account (SA) with RBAC permissions, follow these steps:

 



1️.Create a Service Account

# kubectl create serviceaccount kustav-sa

  • This creates a service account named kustav-sa in the default namespace.
  • If you need it in a specific namespace, use:

# kubectl create serviceaccount kustav-sa -n finance

2️.Create a Role with Read-Only Permissions

# kubectl create role read-only-role --verb=get,list,watch --resource=pods,services,deployments -n finance

  • This Role allows read-only access to resources (pods, services, deployments) only in the finance namespace.

3️.Bind the Role to the Service Account

# kubectl create rolebinding kustav-readonly-binding --role=read-only-role --serviceaccount=finance:kustav-sa -n finance

  • Binds read-only-role to kustav-sa in the finance namespace.

4️.Get the Service Account Token

# kubectl get secret $(kubectl get sa kustav-sa -n finance -o jsonpath="{.secrets[0].name}") -n finance -o jsonpath="{.data.token}" | base64 --decode

  • Retrieves the token for the service account.

5️.Use the Token for Authentication

Create a kubeconfig file for API access:

kubectl config set-cluster kubernetes --server=https://<KUBE_API_SERVER>:6443 --certificate-authority=ca.crt --kubeconfig=kustav-sa.kubeconfig

kubectl config set-credentials kustav-sa --token=<TOKEN> --kubeconfig=kustav-sa.kubeconfig

kubectl config set-context kustav-sa-context --cluster=kubernetes --namespace=finance --user=kustav-sa --kubeconfig=kustav-sa.kubeconfig

kubectl config use-context kustav-sa-context --kubeconfig=kustav-sa.kubeconfig

  • Replace <TOKEN> with the actual token retrieved in step 4.

6️.Verify Permissions

kubectl --kubeconfig=kustav-sa.kubeconfig auth can-i list pods -n finance

kubectl --kubeconfig=kustav-sa.kubeconfig get pods -n finance

  • Ensures the service account has read-only access.

Now, kustav-sa can access pods, services, deployments in the finance namespace with read-only permissions!


No comments:

Post a Comment