Introduction
Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization.
RBAC authorization uses the rbac.authorization.k8s.io
API group to drive authorization decisions, allowing you to dynamically configure policies through the Kubernetes API.
Enable RBAC
To enable RBAC, start the API server with the --authorization-mode
flag set to a comma-separated list that includes RBAC, for example:
kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options
Note: From Kubernetes 1.6 onwards, Role-based Access Control is enabled by default. RBAC allows you to specify which types of actions are permitted depending on the user and their role in your organization.
RBAC API
Role and ClusterRole
An RBAC Role or ClusterRole contains rules that represent a set of permissions. Permissions are purely additive (there are no "deny" rules).
A Role always sets permissions within a particular namespace; when you create a Role, you have to specify the namespace it belongs in.
ClusterRole, by contrast, is a non-namespaced resource. The resources have different names (Role and ClusterRole) because a Kubernetes object always has to be either namespaced or not namespaced; it can't be both.
ClusterRoles have several uses. You can use a ClusterRole to:
- define permissions on namespaced resources and be granted access within individual namespace(s)
- define permissions on namespaced resources and be granted access across all namespaces
- define permissions on cluster-scoped resources
If you want to define a role within a namespace, use a Role; if you want to define a role cluster-wide, use a ClusterRole.
Role example
Here's an example Role in the "default" namespace that can be used to grant read access to pods:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
ClusterRole example
A ClusterRole can be used to grant the same permissions as a Role. Because ClusterRoles are cluster-scoped, you can also use them to grant access to:
- cluster-scoped resources (like nodes)
- non-resource endpoints (like /healthz)
- namespaced resources (like Pods), across all namespaces
For example: you can use a ClusterRole to allow a particular user to run kubectl get pods --all-namespaces
Here is an example of a ClusterRole that can be used to grant read access to secrets in any particular namespace, or across all namespaces (depending on how it is bound):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
The name of a Role or a ClusterRole object must be a valid path segment name.
RoleBinding and ClusterRoleBinding
A role binding grants the permissions defined in a role to a user or set of users. It holds a list of subjects (users, groups, or service accounts), and a reference to the role being granted. A RoleBinding grants permissions within a specific namespace whereas a ClusterRoleBinding grants that access cluster-wide.
A RoleBinding may reference any Role in the same namespace. Alternatively, a RoleBinding can reference a ClusterRole and bind that ClusterRole to the namespace of the RoleBinding. If you want to bind a ClusterRole to all the namespaces in your cluster, you use a ClusterRoleBinding.
The name of a RoleBinding or ClusterRoleBinding object must be a valid path segment name.
RoleBinding examples
Here is an example of a RoleBinding that grants the "pod-reader" Role to the user "jane" within the "default" namespace. This allows "jane" to read pods in the "default" namespace.
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: jane # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
A RoleBinding can also reference a ClusterRole 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.
For instance, even though the following RoleBinding refers to a ClusterRole, "dave" (the subject, case sensitive) will only be able to read Secrets in the "development" namespace, because the RoleBinding's namespace (in its metadata) is "development".
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "dave" to read secrets in the "development" namespace.
# You need to already have a ClusterRole named "secret-reader".
kind: RoleBinding
metadata:
name: read-secrets
#
# The namespace of the RoleBinding determines where the permissions are granted.
# This only grants permissions within the "development" namespace.
namespace: development
subjects:
- kind: User
name: dave # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding example
To grant permissions across a whole cluster, you can use a ClusterRoleBinding. The following ClusterRoleBinding allows any user in the group "manager" to read secrets in any namespace.
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
After you create a binding, you cannot change the Role or ClusterRole that it refers to. If you try to change a binding's roleRef
, you get a validation error. If you do want to change the roleRef
for a binding, you need to remove the binding object and create a replacement.
There are two reasons for this restriction:
- Making
roleRef
immutable allows granting someoneupdate
permission on an existing binding object, so that they can manage the list of subjects, without being able to change the role that is granted to those subjects. - A binding to a different role is a fundamentally different binding. Requiring a binding to be deleted/recreated in order to change the
roleRef
ensures the full list of subjects in the binding is intended to be granted the new role (as opposed to enabling or accidentally modifying only the roleRef without verifying all of the existing subjects should be given the new role's permissions).
The kubectl auth reconcile
command-line utility creates or updates a manifest file containing RBAC objects, and handles deleting and recreating binding objects if required to change the role they refer to. See command usage and examples for more information.
Examples: Restricting a user account's access using RBAC
The following examples utilize the default ClusterRoles provided with Kubernetes
Example 1: Grant a user read/write access to a particular namespace
To restrict a user's access to a particular namespace, we can use either the edit
or the admin
role. If your charts create or interact with Roles and Rolebindings, you'll want to use the admin
ClusterRole.
Additionally, you may also create a RoleBinding with cluster-admin
access. Granting a user cluster-admin
access at the namespace scope provides full control over every resource in the namespace, including the namespace itself.
For this example, we will create a user with the edit
Role. First, create the namespace:
$ kubectl create namespace test
Now, create a RoleBinding in that namespace, granting the user the edit
role.
$ kubectl create rolebinding sam-edit
--clusterrole edit \
--user sam \
--namespace test
Example 2: Grant a user read/write access at the cluster scope
If a user wishes to install a chart that installs cluster-scope resources (namespaces, roles, custom resource definitions, etc.), they will require cluster-scope write access.
To do that, grant the user either admin
or cluster-admin
access.
Granting a user cluster-admin
access grants them access to absolutely every resource available in Kubernetes, including node access with kubectl drain
and other administrative tasks. It is highly recommended to consider providing the user admin
access instead, or to create a custom ClusterRole tailored to their needs.
$ kubectl create clusterrolebinding sam-view
--clusterrole view \
--user sam
$ kubectl create clusterrolebinding sam-secret-reader
--clusterrole secret-reader \
--user sam
Example 3: Grant a user read-only access to a particular namespace
You might've noticed that there is no ClusterRole available for viewing secrets. The view ClusterRole does not grant a user read access to Secrets due to escalation concerns. Helm stores release metadata as Secrets by default.
In order for a user to run helm list
, they need to be able to read these secrets. For that, we will create a special secret-reader
ClusterRole.
Create the file cluster-role-secret-reader.yaml
and write the following content into the file:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Then, create the ClusterRole using
$ kubectl create -f clusterrole-secret-reader.yaml
Once that's done, we can grant a user read access to most resources, and then grant them read access to secrets:
$ kubectl create namespace dev
$ kubectl create rolebinding sam-view
--clusterrole view \
--user sam \
--namespace dev
$ kubectl create rolebinding sam-secret-reader
--clusterrole secret-reader \
--user sam \
--namespace dev
Example 4: Grant a user read-only access at the cluster scope
In certain scenarios, it may be beneficial to grant a user cluster-scope access. For example, if a user wants to run the command helm list --all-namespaces
, the API requires the user has cluster-scope read access.
To do that, grant the user both view
and secret-reader
access as described above, but with a ClusterRoleBinding.
$ kubectl create clusterrolebinding sam-view
--clusterrole view \
--user sam
$ kubectl create clusterrolebinding sam-secret-reader
--clusterrole secret-reader \
--user sam
Conclusion
From the above examples, you can observe some behaviors and limitations of RBAC resources:
- Roles and role bindings must exist in the same namespace.
- Role bindings can exist in separate namespaces to service accounts.
- Role bindings can link cluster roles, but they only grant access to the namespace of the role binding.
- Cluster role bindings link accounts to cluster roles and grant access across all resources.
- Cluster role bindings can not reference roles.
With RBAC, you can:
- grant privileged operations (creating cluster-wide resources, like new roles) to administrators
- limit a user's ability to create resources (pods, persistent volumes, deployments) to specific namespaces, or in cluster-wide scopes (resource quotas, roles, custom resource definitions)
- limit a user's ability to view resources either in specific namespaces or at a cluster-wide scope.
Top comments (0)