Skip to Content
Last repository update 9/10/2025 🎉
DocsKubernetesAuthorization

Authorization

Authorization Mechanisms (Modes)

Refer here  for more details.

In summary;

ModeDescription
AlwaysAllowAllows all requests without any authorization checks.
AlwaysDenyBlocks all requests.
Node AuthorizationA special-purpose authorization mode that authorizes API requests made by kubelets.
ABACIt defines an access control paradigm whereby access rights are granted to users through the use of policies that combine attributes together.
RBACIt is a method of regulating (control) access to resources in a Kubernetes cluster based on the roles of individual users or service accounts.
WebhookA mode that allows you to manage authorization externally. For example, Open Policy Agent (OPA).

By default, the mode is set to AlwaysAllow in the kube-apiserver. You can change the mode by setting the --authorization-mode flag in the kube-apiserver. You can also specify multiple modes by separating them with a comma. When you specify multiple nodes, the kube-apiserver will try to authorize the request with the first mode in the list. If the request is denied, it will try the next mode in the list.

--authorization-mode=RBAC,ABAC,Webhook

Node Authorization

Reference 

The node authorizer allows a kubelet to perform API operations. All these operations are handled by node authorizer. So, we know that kubelet is part of a system nodes group and have a prefix system:node. The kubelet will be granted these privileges after the node authorizer has authorized the kubelet so that it can perform the following operations.

Read operations;

  • services
  • endpoints
  • nodes
  • pods
  • secrets, configmaps, persistent volume claims and persistent volumes related to pods bound to the kubelet’s node

Write operations;

  • node status
  • pod status
  • events

Attribute-based Access Control (ABAC)

Reference 

ABAC is a method of restricting access to resources based on the attributes of the user. It is a static file that defines the access control policy. The policy file is a set of rules that specify what kind of access is granted to which users.

Step 1: Create a Policy File

For example, the following policy file

  • allows Alice to create pods and get pods in the default namespace.
  • allows Bob to get pods in the prod namespace, but not create pods.
  • allows group dev to access all resources in all namespaces.
policy.jsonl
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": { "user": "alice", "namespace": "default", "resource": "pods", "readonly": false}} {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "prod", "resource": "pods", "readonly": true}} {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "dev", "namespace": "*", "resource": "*"}}
  • you can specify multiple rules in the policy file.

Step 2: Enable ABAC mode

Once you have the policy file, you will need to enable ABAC in the kube-apiserver by setting the --authorization-mode flag to ABAC and the --authorization-policy-file flag to the path of the policy file. But this method is not recommended, as everytime you need to update the policy file, you need to restart the kube-apiserver.

/etc/kubernetes/manifests/kube-apiserver.yaml
--authorization-mode=ABAC --authorization-policy-file=policy.jsonl
  • Remember to mount the policy file through a volume.

Step 3: Create a new user and test

You can create a service account and use service account token to create a new user.

# create a new service account kubectl create serviceaccount alice

Create service account token.

sa-token-secret.yaml
apiVersion: v1 kind: Secret metadata: name: alice-token annotations: kubernetes.io/service-account.name: alice type: kubernetes.io/service-account-token

Retrieve the service account token and store the token securely in a file as it is used to authenticate the user.

kubectl get secret alice-token -o jsonpath='{.data.token}' | base64 --decode > token.txt

Setup new user credentials with the token.

export ALICE_TOKEN=$(cat token.txt) kubectl config set-credetials alice --token=$ALICE_TOKEN

Setup new context with the new user.

kubectl config set-context alice-context --user=alice --cluster=kubernetes --namespace=default

Verify the permissions of the user.

kubectl get pods -n default # should work kubectl get secrets -n default # should not work

Role-based Access Control (RBAC)

Reference 

RBAC is a method of regulating (control) access to resources based on the roles of individual users or service accounts. So we will create and define a role with a set of permissions and then bind the role to a user or service account.

Before we dive into RBAC, we need to understand what resources are under namespace and cluster scope (non-namespaced resources).

# list all resources under namespace kubectl api-resources --namespaced=true # this will help you to get the verb kubectl api-resources --namespaced=true --sort-by name -o wide
NameAPI VersionKind
bindingsv1Binding
configmapsv1ConfigMap
endpointsv1Endpoints
eventsv1Event
limitrangesv1LimitRange
persistentvolumeclaimsv1PersistentVolumeClaim
podsv1Pod
podtemplatesv1PodTemplate
replicationcontrollersv1ReplicationController
resourcequotasv1ResourceQuota
secretsv1Secret
serviceaccountsv1ServiceAccount
servicesv1Service
controllerrevisionsapps/v1ControllerRevision
daemonsetsapps/v1DaemonSet
deploymentsapps/v1Deployment
replicasetsapps/v1ReplicaSet
statefulsetsapps/v1StatefulSet
localsubjectaccessreviewsauthorization.k8s.io/v1LocalSubjectAccessReview
horizontalpodautoscalersautoscaling/v2HorizontalPodAutoscaler
cronjobsbatch/v1CronJob
jobsbatch/v1Job
leasescoordination.k8s.io/v1Lease
endpointslicesdiscovery.k8s.io/v1EndpointSlice
eventsevents.k8s.io/v1Event
ingressesnetworking.k8s.io/v1Ingress
networkpoliciesnetworking.k8s.io/v1NetworkPolicy
poddisruptionbudgetspolicy/v1PodDisruptionBudget
contourconfigurationsprojectcontour.io/v1alpha1ContourConfiguration
contourdeploymentsprojectcontour.io/v1alpha1ContourDeployment
extensionservicesprojectcontour.io/v1alpha1ExtensionService
httpproxiesprojectcontour.io/v1HTTPProxy
tlscertificatedelegationsprojectcontour.io/v1TLSCertificateDelegation
rolebindingsrbac.authorization.k8s.io/v1RoleBinding
rolesrbac.authorization.k8s.io/v1Role
csistoragecapacitiesstorage.k8s.io/v1CSIStorageCapacity

Now, from the above table, we can see that roles and rolebindings are under namespace scope, meaning that they are created within a namespace. If you do not specify a namespace, they will be created in the default namespace and control access to resources within that namespace.

Step 1: Create a Role

You can use the following command to get the verb for the resource.

kubectl api-resources --namespaced=true --sort-by name -o wide
role.yaml
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: developer rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["create", "delete"] - apiGroups: [""] resources: ["secrets"] # use * to allow all resources verbs: ["get"] # use * to allow all verbs resourceNames: ["secret-name", "my-secret"] # optional
  • apiGroups - The API group of the resource. If you are not sure, you can see the above table (API Version).
  • resourceNames - The names of the resources that the rule applies to. If you do not specify, the rule applies to all resources of the specified type.
    • In this example, the user can only read the secrets with the name secret-name and my-secret.
    • secret-name and my-secret are the names of the secrets (metadata name).
# You cannot create a role with different rules, as they will mix it up kubectl create role developer --verb=get,watch,list --resource=pods kubectl create role developer --verb=create,delete --resource=deployments.apps # need to append .apps due to apiGroups kubectl create role developer --verb=get --resource=secrets --resource-name=secret-name --resource-name=my-secret kubectl get roles

Step 2: Create a RoleBinding

Link the role to a user, group or service account.

rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: developer-binding subjects: # users, groups, or service accounts - kind: User name: user1 # user name apiGroup: rbac.authorization.k8s.io - kind: Group name: backend-developers # group name apiGroup: rbac.authorization.k8s.io - kind: ServiceAccount name: my-service-account # service account name namespace: default # namespace of the service account - kind: Group name: system:serviceaccounts:default # all service accounts in the default namespace apiGroup: rbac.authorization.k8s.io - kind: Group name: system:serviceaccounts # all service accounts in any namespace apiGroup: rbac.authorization.k8s.io - kind: Group name: system:authenticated # all authenticated users apiGroup: rbac.authorization.k8s.io - kind: Group name: system:unauthenticated # all unauthenticated users apiGroup: rbac.authorization.k8s.io roleRef: apiGroup: rbac.authorization.k8s.io kind: Role # Role or ClusterRole name: developer # role name
  • You can also reference a ClusterRole instead of a role to grant the permissions defined in that ClusterRole to resources inside the RoleBinding’s namespace. This kind of reference lets you define a set of common roles across your cluster, then reuse them within multiple namespaces.
kubectl create rolebinding developer-binding --role=developer --user=user1 kubectl create rolebinding developer-binding --role=developer --group=backend-developers kubectl create rolebinding developer-binding --role=developer --serviceaccount=<namespace>:<service-account-name> kubectl create rolebinding developer-binding --role=developer --serviceaccount=default:my-service-account kubectl get rolebinding

Step 3: Verify the access (Optional)

You can check if the user have access to a resource by using the following command.

kubectl auth can-i delete nodes kubectl auth can-i get pods --as <name-of-the-user> kubectl auth can-i get pods --as developer # check if the user can create deployments in the prod namespace kubectl auth can-i create deployments --as developer --namespace prod # Check if the group 'developers' can delete nodes kubectl auth can-i delete nodes --as-group=developers # Check if the service account 'my-service-account' in the 'default' namespace can get pods kubectl auth can-i get pods --as=system:serviceaccount:default:my-service-account # Check if the service account 'my-service-account' in the 'default' namespace can create deployments in the 'prod' namespace kubectl auth can-i create deployments --as=system:serviceaccount:default:my-service-account --namespace=prod
Last updated on