Skip to content

Manage role based access control (RBAC)

Kubernetes implements an RBAC framework to govern access to resources within a cluster and forms part of the overall Authentication, Authorization and Admission control framework.

Four steps are needed for a Human user or a service account to gain access to a resource:

graph LR
    %% External Clients
    User["💻 Human User"]:::client
    ServiceAccount{"Pod<br/>(Kubernetes<br/>Service Account)"}:::pod

    %% API Server Boundary
    subgraph API [Kubernetes API Server]
        direction LR

        AuthN("â‘ <br/><br/>Authentication"):::puzzle
        AuthZ("â‘¡<br/><br/>Authorization"):::puzzle
        AdminCtrl("â‘¢<br/><br/>Admission<br/>Control"):::puzzle

        AuthN --> AuthZ
        AuthZ --> AdminCtrl
    end

    %% Backend Storage
    subgraph Data [ Objects ]
        direction TB
        DB1[(" API ")]:::database
        DB2[(" API ")]:::database
        DB3[(" API ")]:::database
    end

    %% Routing / Connections
    User --> AuthN
    ServiceAccount --> AuthN
    AdminCtrl -->|"â‘£"| DB2

To determine who (or what) has access to which resources, a number of steps have to be executed.

Step 1 - Authentication

First step is Authentication which is how a user or service account identifies itself. Depending on the source, a corresponding authentication module is used. Authentication modules include the ability to authenticate from the following:

  • Client Certificate
  • Password
  • Plain Tokens
  • Bootstrap Tokens
  • JWT Tokens (for service accounts)

All authentication is handled via HTTP over TLS.

Step 2 - Authorization

After a user or service account is authenticated, the request must then be authorised. Any authentication request is followed by some kind of action request, and the action defines the object(s) that request needs to apply to, and what the action is. For example, to list the pods in a given namespace.

Steps 3 & 4 - Admission Control

Admission Control Modules can modify or reject requests. In addition to the attributes available to Authorisation Modules, Admission Control Modules can access the contents of the object that is being created or updated. They act on objects being created, deleted, updated or connected (proxy), but not reads.

Role and Rolebindings

Implementing RBAC rules largely involves two object types within Kubernetes - role and rolebindings:

graph TD
    subgraph Cluster_Env [Cluster]

        subgraph Namespace_A [Namespace A]
            direction RL
            RolebindingA((Rolebinding))
            RoleA((Role))

            RolebindingA --> RoleA
        end

        subgraph Namespace_B [Namespace B]
            direction RL
            RolebindingB((Rolebinding))
            RoleB((Role))

            RolebindingB --> RoleB
        end

        ClusterRolebinding((Cluster<br/>Rolebinding))
        ClusterRole((Cluster Role))

        ClusterRolebinding --> ClusterRole

        User["👤<br/>User / Group / Service Account"]:::userNode

        RolebindingA -.-> User
        RolebindingB -.-> User
        ClusterRolebinding -.-> User
    end

A role grants access to resources within a single namespace.

A rolebinding grants the permissions from a role to a user, group or service account within a single namespace.

clusterrole and clusterrolebindings operate similarly, but provide access to cluster-scoped resources.

kubectl api-resources --namespaced=false can be used to determine which resource types are not namespaced. Examples include: node, persistentvolume, storageclass and users.

Users can either be serviceaccounts or users. The former is typically used to authenticate applications, the latter for human users.

To test, the below creates namespace, serviceaccount, role and rolebinding

apiVersion: v1
kind: Namespace
metadata:
 name: rbac-test
apiVersion: v1
kind: ServiceAccount
metadata:
 name: rbac-test-sa
 namespace: rbac-test

apiGroup : Determines which API group to apply this to.
resources: Which resource types to apply this to.
verbs: What we can do to these objects (ie create, delete, watch, etc)

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

We can then validate this with kubectl. The following returns yes as that service account can get pods

kubectl -n rbac-test --as=system:serviceaccount:rbac-test:rbac-test-sa auth can-i get pods
yes

However with secrets, it returns no

kubectl -n rbac-test --as=system:serviceaccount:rbac-test:rbac-test-sa auth can-i get secrets
no

Exam Tip

roles and rolebindings are namespace-scoped. clusterRoles and clusterBindings are cluster-scoped.

Exam Tip

roles provide the "persona" - ie admin, reader, deployer, etc. bindings provide the glue between a user and a role.