From e881e91b9a1799237d682b02e9b6881a77a7c14b Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Wed, 18 Mar 2020 22:50:44 +0000 Subject: [PATCH] Improve RBAC guide (#17538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update to match website style guide * Use glossary shortcodes * Overall tidying * Drop mention of old (unsupported) releases * Reword RBAC notes & warnings * Write “role bindings” as two words * Tweak RBAC guide wording * Tweak RBAC out-of-the-box roles table * Mention other authorizers There are other authorizers than RBAC and ABAC; hint that these exist and that the API server might run with these configured. * Fix formatting of API discovery roles Also add table caption * Drop incorrect reference to cluster-status * Drop vestigial RBAC warning --- .../docs/reference/access-authn-authz/rbac.md | 707 +++++++++++------- 1 file changed, 425 insertions(+), 282 deletions(-) diff --git a/content/en/docs/reference/access-authn-authz/rbac.md b/content/en/docs/reference/access-authn-authz/rbac.md index 3e18ae283e..b4e2f5ed6e 100644 --- a/content/en/docs/reference/access-authn-authz/rbac.md +++ b/content/en/docs/reference/access-authn-authz/rbac.md @@ -10,35 +10,61 @@ weight: 70 --- {{% capture overview %}} -Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. +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. {{% /capture %}} {{% capture body %}} -`RBAC` uses the `rbac.authorization.k8s.io` {{< glossary_tooltip text="API Group" term_id="api-group" >}} -to drive authorization decisions, allowing admins to dynamically configure policies -through the Kubernetes API. +RBAC authorization uses the `rbac.authorization.k8s.io` +{{< glossary_tooltip text="API group" term_id="api-group" >}} to drive authorization +decisions, allowing you to dynamically configure policies through the Kubernetes API. -As of 1.8, RBAC mode is stable and backed by the rbac.authorization.k8s.io/v1 API. +To enable RBAC, start the {{< glossary_tooltip text="API server" term_id="kube-apiserver" >}} +with the `--authorization-mode` flag set to a comma-separated list that includes `RBAC`; +for example: +```shell +kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options +``` -To enable RBAC, start the apiserver with `--authorization-mode=RBAC`. +## API objects {#api-overview} -## API Overview +The RBAC API declares four kinds of Kubernetes object: _Role_, _ClusterRole_, +_RoleBinding_ and _ClusterRoleBinding_. You can +[describe objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/#understanding-kubernetes-objects), +or amend them, using tools such as `kubectl,` just like any other Kubernetes object. -The RBAC API declares four top-level types which will be covered in this -section. Users can interact with these resources as they would with any other -API resource (via `kubectl`, API calls, etc.). For instance, -`kubectl apply -f (resource).yml` can be used with any of these examples, -though readers who wish to follow along should review the section on -bootstrapping first. +{{< caution >}} +These objects, by design, impose access restrictions. If you are making changes +to a cluster as you learn, see +[privilege escalation prevention and bootstrapping](#privilege-escalation-prevention-and-bootstrapping) +to understand how those restrictions can prevent you making some changes. +{{< /caution >}} ### Role and ClusterRole -In the RBAC API, a role contains rules that represent a set of permissions. +An RBAC _Role_ or _ClusterRole_ contains rules that represent a set of permissions. Permissions are purely additive (there are no "deny" rules). -A role can be defined within a namespace with a `Role`, or cluster-wide with a `ClusterRole`. -A `Role` can only be used to grant access to resources within a single namespace. -Here's an example `Role` in the "default" namespace that can be used to grant read access to pods: +A Role always sets permissions within a particular {{< glossary_tooltip text="namespace" term_id="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: + +1. define permissions on namespaced resources and be granted within individual namespace(s) +1. define permissions on namespaced resources and be granted across all namespaces +1. 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 +{{< glossary_tooltip text="pods" term_id="pod" >}}: ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -52,14 +78,19 @@ rules: verbs: ["get", "watch", "list"] ``` -A `ClusterRole` can be used to grant the same permissions as a `Role`, -but because they are cluster-scoped, they can also be used to grant access to: +#### ClusterRole example -* cluster-scoped resources (like nodes) -* non-resource endpoints (like "/healthz") -* namespaced resources (like pods) across all namespaces (needed to run `kubectl get pods --all-namespaces`, for 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: -The following `ClusterRole` can be used to grant read access to secrets in any particular namespace, +* cluster-scoped resources (like {{< glossary_tooltip text="nodes" term_id="node" >}}) +* 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 +{{< glossary_tooltip text="secrets" term_id="secret" >}} in any particular namespace, or across all namespaces (depending on how it is [bound](#rolebinding-and-clusterrolebinding)): ```yaml @@ -70,6 +101,9 @@ metadata: 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"] ``` @@ -80,51 +114,65 @@ The name of a Role or a ClusterRole object must be a valid ### 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. -Permissions can be granted within a namespace with a `RoleBinding`, or cluster-wide with a `ClusterRoleBinding`. +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 a `Role` in the same namespace. -The name of a `RoleBinding` object must be a valid +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](/docs/concepts/overview/working-with-objects/names#path-segment-names). -The following `RoleBinding` grants the "pod-reader" role to the user "jane" within the "default" namespace. -This allows "jane" to read pods in the "default" namespace. +#### RoleBinding examples {#rolebinding-example} -`roleRef` is how you will actually create the binding. The `kind` will be either `Role` or `ClusterRole`, and the `name` will reference the name of the specific `Role` or `ClusterRole` you want. In the example below, this RoleBinding is using `roleRef` to bind the user "jane" to the `Role` created above named `pod-reader`. +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. ```yaml 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 + 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` may also reference a `ClusterRole` to grant the permissions to namespaced -resources defined in the `ClusterRole` within the `RoleBinding`'s namespace. -This allows administrators to define a set of common roles for the entire cluster, -then reuse them within multiple namespaces. +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 (the namespace of the `RoleBinding`). +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". ```yaml 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 - namespace: development # This only grants permissions within the "development" namespace. + # + # 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 @@ -135,10 +183,10 @@ roleRef: apiGroup: rbac.authorization.k8s.io ``` -Finally, a `ClusterRoleBinding` may be used to grant permission at the cluster level and in all namespaces. - The name of a `ClusterRoleBinding` object must be a valid -[path segment name](/docs/concepts/overview/working-with-objects/names#path-segment-names). -The following `ClusterRoleBinding` allows any user in the group "manager" to read +#### 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. ```yaml @@ -157,37 +205,43 @@ roleRef: apiGroup: rbac.authorization.k8s.io ``` -You cannot modify which `Role` or `ClusterRole` a binding object refers to. -Attempts to change the `roleRef` field of a binding object will result in a validation error. -To change the `roleRef` field on an existing binding object, the binding object must be deleted and recreated. -There are two primary reasons for this restriction: +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. -1. A binding to a different role is a fundamentally different binding. +There are two reasons for this restriction: + +1. Making `roleRef` immutable allows granting someone `update` 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. +1. 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 accidentally modifying just the roleRef -without verifying all of the existing subjects should be given the new role's permissions). -2. Making `roleRef` immutable allows giving `update` permission on an existing binding object -to a user, which lets them manage the list of subjects, without being able to change the -role that is granted to those subjects. +the new role (as opposed to enabling accidentally modifying just 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. +and handles deleting and recreating binding objects if required to change the role they refer to. See [command usage and examples](#kubectl-auth-reconcile) for more information. -### Referring to Resources +### Referring to resources -Most resources are represented by a string representation of their name, such as "pods", just as it -appears in the URL for the relevant API endpoint. However, some Kubernetes APIs involve a -"subresource", such as the logs for a pod. The URL for the pods logs endpoint is: +In the Kubernetes API, most resources are represented and accessed using a string representation of +their object name, such as `pods` for a Pod. RBAC refers to resources using exactly the same +name that appears in the URL for the relevant API endpoint. +Some Kubernetes APIs involve a +_subresource_, such as the logs for a Pod. A request for a Pod's logs looks like: ```http GET /api/v1/namespaces/{namespace}/pods/{name}/log ``` -In this case, "pods" is the namespaced resource, and "log" is a subresource of pods. To represent -this in an RBAC role, use a slash to delimit the resource and subresource. To allow a subject -to read both pods and pod logs, you would write: +In this case, `pods` is the namespaced resource for Pod resources, and `log` is a +subresource of `pods`. To represent this in an RBAC role, use a slash (`/`) to +delimit the resource and subresource. To allow a subject to read `pods` and +also access the `log` subresource for each of those Pods, you write: ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -201,9 +255,11 @@ rules: verbs: ["get", "list"] ``` -Resources can also be referred to by name for certain requests through the `resourceNames` list. -When specified, requests can be restricted to individual instances of a resource. To restrict a -subject to only "get" and "update" a single configmap, you would write: +You can also refer to resources by name for certain requests through the `resourceNames` list. +When specified, requests can be restricted to individual instances of a resource. +Here is an example that restricts its subject to only `get` or `update` a +{{< glossary_tooltip term_id="ConfigMap" >}} named `my-configmap`: + ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -213,19 +269,30 @@ metadata: name: configmap-updater rules: - apiGroups: [""] + # + # at the HTTP level, the name of the resource for accessing ConfigMap + # objects is "configmaps" resources: ["configmaps"] resourceNames: ["my-configmap"] verbs: ["update", "get"] ``` -Note that `create` requests cannot be restricted by resourceName, as the object name is not known at -authorization time. The other exception is `deletecollection`. +{{< note >}} +You cannot restrict `create` or `deletecollection` requests by resourceName. For `create`, this +limitation is because the object name is not known at authorization time. +{{< /note >}} + ### Aggregated ClusterRoles -As of 1.9, ClusterRoles can be created by combining other ClusterRoles using an `aggregationRule`. The -permissions of aggregated ClusterRoles are controller-managed, and filled in by unioning the rules of any -ClusterRole that matches the provided label selector. An example aggregated ClusterRole: +You can _aggregate_ several ClusterRoles into one combined ClusterRole. +A controller, running as part of the cluster control plane, watches for ClusterRole +objects with an `aggregationRule` set. The `aggregationRule` defines a label +{{< glossary_tooltip text="selector" term_id="selector" >}} that the controller +uses to match other ClusterRole objects that should be combined into the `rules` +field of this one. + +Here is an example aggregated ClusterRole: ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -236,12 +303,13 @@ aggregationRule: clusterRoleSelectors: - matchLabels: rbac.example.com/aggregate-to-monitoring: "true" -rules: [] # Rules are automatically filled in by the controller manager. +rules: [] # The control plane automatically fills in the rules ``` -Creating a ClusterRole that matches the label selector will add rules to the aggregated ClusterRole. In this case -rules can be added to the "monitoring" ClusterRole by creating another ClusterRole that has the label -`rbac.example.com/aggregate-to-monitoring: true`. +If you create a new ClusterRole that matches the label selector of an existing aggregated ClusterRole, +that change triggers adding the new rules into the aggregated ClusterRole. +Here is an example that adds rules to the "monitoring" ClusterRole, by creating another +ClusterRole labeled `rbac.example.com/aggregate-to-monitoring: true`. ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -250,19 +318,22 @@ metadata: name: monitoring-endpoints labels: rbac.example.com/aggregate-to-monitoring: "true" -# These rules will be added to the "monitoring" role. +# When you create the "monitoring-endpoints" ClusterRole, +# the rules below will be added to the "monitoring" ClusterRole. rules: - apiGroups: [""] resources: ["services", "endpoints", "pods"] verbs: ["get", "list", "watch"] ``` -The default user-facing roles (described below) use ClusterRole aggregation. This lets admins include rules -for custom resources, such as those served by CustomResourceDefinitions or Aggregated API servers, on the -default roles. +The [default user-facing roles](#default-roles-and-rolebindings) use ClusterRole aggregation. This lets you, +as a cluster administrator, include rules for custom resources, such as those served by +{{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinitions" >}} +or aggregated API servers, to extend the default roles. -For example, the following ClusterRoles let the "admin" and "edit" default roles manage the custom resource -"CronTabs" and the "view" role perform read-only actions on the resource. +For example: the following ClusterRoles let the "admin" and "edit" default roles manage the custom resource +named CronTab, whereas the "view" role can perform just read actions on CronTab resources. +You can assume that CronTab objects are named `"crontabs"` in URLs as seen by the API server. ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -291,60 +362,87 @@ rules: verbs: ["get", "list", "watch"] ``` -#### Role Examples +#### Role examples -Only the `rules` section is shown in the following examples. +The following examples are excerpts from Role or ClusterRole objects, showing only +the `rules` section. -Allow reading the resource "pods" in the core {{< glossary_tooltip text="API Group" term_id="api-group" >}}: +Allow reading `"pods"` resources in the core +{{< glossary_tooltip text="API Group" term_id="api-group" >}}: ```yaml rules: - apiGroups: [""] + # + # at the HTTP level, the name of the resource for accessing Pod + # objects is "pods" resources: ["pods"] verbs: ["get", "list", "watch"] ``` -Allow reading/writing "deployments" in both the "extensions" and "apps" API groups: +Allow reading/writing Deployments (at the HTTP level: objects with `"deployments"` +in the resource part of their URL) in both the `"extensions"` and `"apps"` API groups: ```yaml rules: - apiGroups: ["extensions", "apps"] + # + # at the HTTP level, the name of the resource for accessing Deployment + # objects is "deployments" resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ``` -Allow reading "pods" and reading/writing "jobs": +Allow reading Pods in the core API group, as well as reading or writing Job +resources in the `"batch"` or `"extensions"` API groups: ```yaml rules: - apiGroups: [""] + # + # at the HTTP level, the name of the resource for accessing Pod + # objects is "pods" resources: ["pods"] verbs: ["get", "list", "watch"] - apiGroups: ["batch", "extensions"] + # + # at the HTTP level, the name of the resource for accessing Job + # objects is "jobs" resources: ["jobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ``` -Allow reading a `ConfigMap` named "my-config" (must be bound with a `RoleBinding` to limit to a single `ConfigMap` in a single namespace): +Allow reading a ConfigMap named "my-config" (must be bound with a +RoleBinding to limit to a single ConfigMap in a single namespace): ```yaml rules: - apiGroups: [""] + # + # at the HTTP level, the name of the resource for accessing ConfigMap + # objects is "configmaps" resources: ["configmaps"] resourceNames: ["my-config"] verbs: ["get"] ``` -Allow reading the resource "nodes" in the core group (because a `Node` is cluster-scoped, this must be in a `ClusterRole` bound with a `ClusterRoleBinding` to be effective): +Allow reading the resource `"nodes"` in the core group (because a +Node is cluster-scoped, this must be in a ClusterRole bound with a +ClusterRoleBinding to be effective): ```yaml rules: - apiGroups: [""] + # + # at the HTTP level, the name of the resource for accessing Node + # objects is "nodes" resources: ["nodes"] verbs: ["get", "list", "watch"] ``` -Allow "GET" and "POST" requests to the non-resource endpoint "/healthz" and all subpaths (must be in a `ClusterRole` bound with a `ClusterRoleBinding` to be effective): +Allow GET and POST requests to the non-resource endpoint `/healthz` and +all subpaths (must be in a ClusterRole bound with a ClusterRoleBinding +to be effective): ```yaml rules: @@ -352,32 +450,44 @@ rules: verbs: ["get", "post"] ``` -### Referring to Subjects +### Referring to subjects -A `RoleBinding` or `ClusterRoleBinding` binds a role to *subjects*. -Subjects can be groups, users or service accounts. +A RoleBinding or ClusterRoleBinding binds a role to subjects. +Subjects can be groups, users or +{{< glossary_tooltip text="ServiceAccounts" term_id="service-account" >}}. -Users are represented by strings. These can be plain usernames, like -"alice", email-style names, like "bob@example.com", or numeric IDs -represented as a string. It is up to the Kubernetes admin to configure -the [authentication modules](/docs/reference/access-authn-authz/authentication/) to produce -usernames in the desired format. The RBAC authorization system does -not require any particular format. However, the prefix `system:` is -reserved for Kubernetes system use, and so the admin should ensure -usernames do not contain this prefix by accident. +Kubernetes represents usernames as strings. +These can be: plain names, such as "alice"; email-style names, like "bob@example.com"; +or numeric user IDs represented as a string. It is up to you as a cluster administrator +to configure the [authentication modules](/docs/reference/access-authn-authz/authentication/) +so that authentication produces usernames in the format you want. -Group information in Kubernetes is currently provided by the Authenticator -modules. Groups, like users, are represented as strings, and that string -has no format requirements, other than that the prefix `system:` is reserved. +{{< caution >}} +The prefix `system:` is reserved for Kubernetes system use, so you should ensure +that you don't have users or groups with names that start with `system:` by +accident. +Other than this special prefix, the RBAC authorization system does not require any format +for usernames. +{{< /caution >}} -[Service Accounts](/docs/tasks/configure-pod-container/configure-service-account/) have usernames with the `system:serviceaccount:` prefix and belong -to groups with the `system:serviceaccounts:` prefix. +In Kubernetes, Authenticator modules provide group information. +Groups, like users, are represented as strings, and that string has no format requirements, +other than that the prefix `system:` is reserved. -#### Role Binding Examples +[ServiceAccounts](/docs/tasks/configure-pod-container/configure-service-account/) have names prefixed +with `system:serviceaccount:`, and belong to groups that have names prefixed with `system:serviceaccounts:`. -Only the `subjects` section of a `RoleBinding` is shown in the following examples. +{{< note >}} +- `system:serviceaccount:` (singular) is the prefix for service account usernames. +- `system:serviceaccounts:` (plural) is the prefix for service account groups. +{{< /note >}} -For a user named "alice@example.com": +#### RoleBinding examples {#role-binding-examples} + +The following examples are `RoleBinding` excerpts that only +show the `subjects` section. + +For a user named `alice@example.com`: ```yaml subjects: @@ -386,7 +496,7 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -For a group named "frontend-admins": +For a group named `frontend-admins`: ```yaml subjects: @@ -395,7 +505,7 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -For the default service account in the kube-system namespace: +For the default service account in the "kube-system" namespace: ```yaml subjects: @@ -413,7 +523,7 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -For all service accounts everywhere: +For all service accounts in any namespace: ```yaml subjects: @@ -422,7 +532,7 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -For all authenticated users (version 1.5+): +For all authenticated users: ```yaml subjects: @@ -431,7 +541,7 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -For all unauthenticated users (version 1.5+): +For all unauthenticated users: ```yaml subjects: @@ -440,7 +550,7 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -For all users (version 1.5+): +For all users: ```yaml subjects: @@ -452,42 +562,51 @@ subjects: apiGroup: rbac.authorization.k8s.io ``` -## Default Roles and Role Bindings +## Default roles and role bindings -API servers create a set of default `ClusterRole` and `ClusterRoleBinding` objects. -Many of these are `system:` prefixed, which indicates that the resource is "owned" by the infrastructure. -Modifications to these resources can result in non-functional clusters. One example is the `system:node` ClusterRole. -This role defines permissions for kubelets. If the role is modified, it can prevent kubelets from working. +API servers create a set of default ClusterRole and ClusterRoleBinding objects. +Many of these are `system:` prefixed, which indicates that the resource is directly +managed by the cluster control plane. +All of the default ClusterRoles and ClusterRoleBindings are labeled with `kubernetes.io/bootstrapping=rbac-defaults`. -All of the default cluster roles and rolebindings are labeled with `kubernetes.io/bootstrapping=rbac-defaults`. +{{< caution >}} +Take care when modifying ClusterRoles and ClusterRoleBindings with names +that have a `system:` prefix. +Modifications to these resources can result in non-functional clusters. +{{< /caution >}} ### Auto-reconciliation At each start-up, the API server updates default cluster roles with any missing permissions, and updates default cluster role bindings with any missing subjects. -This allows the cluster to repair accidental modifications, -and to keep roles and rolebindings up-to-date as permissions and subjects change in new releases. +This allows the cluster to repair accidental modifications, and helps to keep roles and role bindings +up-to-date as permissions and subjects change in new Kubernetes releases. -To opt out of this reconciliation, set the `rbac.authorization.kubernetes.io/autoupdate` +To opt out of this reconciliation, set the `rbac.authorization.kubernetes.io/autoupdate` annotation on a default cluster role or rolebinding to `false`. Be aware that missing default permissions and subjects can result in non-functional clusters. -Auto-reconciliation is enabled in Kubernetes version 1.6+ when the RBAC authorizer is active. +Auto-reconciliation is enabled by default if the RBAC authorizer is active. -### Discovery Roles +### API discovery roles {#discovery-roles} -Default role bindings authorize unauthenticated and authenticated users to read API information that is deemed safe to be publicly accessible (including CustomResourceDefinitions). To disable anonymous unauthenticated access add `--anonymous-auth=false` to the API server configuration. +Default role bindings authorize unauthenticated and authenticated users to read API information that is deemed safe to be publicly accessible (including CustomResourceDefinitions). To disable anonymous unauthenticated access, add `--anonymous-auth=false` to the API server configuration. To view the configuration of these roles via `kubectl` run: -``` +```shell kubectl get clusterroles system:discovery -o yaml ``` -NOTE: editing the role is not recommended as changes will be overwritten on API server restart via auto-reconciliation (see above). +{{< note >}} +If you edit that ClusterRole, your changes will be overwritten on API server restart +via [auto-reconciliation](#auto-reconciliation). To avoid that overwriting, +either do not manually edit the role, or disable auto-reconciliation. +{{< /note >}} - + + @@ -496,30 +615,30 @@ NOTE: editing the role is not recommended as changes will be overwritten on API - + - + - +
Kubernetes RBAC API discovery roles
Default ClusterRole Default ClusterRoleBinding
system:basic-user system:authenticated groupAllows a user read-only access to basic information about themselves. Prior to 1.14, this role was also bound to `system:unauthenticated` by default.Allows a user read-only access to basic information about themselves. Prior to v1.14, this role was also bound to system:unauthenticated by default.
system:discovery system:authenticated groupAllows read-only access to API discovery endpoints needed to discover and negotiate an API level. Prior to 1.14, this role was also bound to `system:unauthenticated` by default.Allows read-only access to API discovery endpoints needed to discover and negotiate an API level. Prior to v1.14, this role was also bound to system:unauthenticated by default.
system:public-info-viewer system:authenticated and system:unauthenticated groupsAllows read-only access to non-sensitive information about the cluster. Introduced in 1.14.Allows read-only access to non-sensitive information about the cluster. Introduced in Kubernetes v1.14.
-### User-facing Roles +### User-facing roles -Some of the default roles are not `system:` prefixed. These are intended to be user-facing roles. -They include super-user roles (`cluster-admin`), -roles intended to be granted cluster-wide using ClusterRoleBindings (`cluster-status`), -and roles intended to be granted within particular namespaces using RoleBindings (`admin`, `edit`, `view`). +Some of the default ClusterRoles are not `system:` prefixed. These are intended to be user-facing roles. +They include super-user roles (`cluster-admin`), roles intended to be granted cluster-wide +using ClusterRoleBindings, and roles intended to be granted within particular +namespaces using RoleBindings (`admin`, `edit`, `view`). -As of 1.9, user-facing roles use [ClusterRole Aggregation](#aggregated-clusterroles) to allow admins to include -rules for custom resources on these roles. To add rules to the "admin", "edit", or "view" role, create a -ClusterRole with one or more of the following labels: +User-facing ClusterRoles use [ClusterRole aggregation](#aggregated-clusterroles) to allow admins to include +rules for custom resources on these ClusterRoles. To add rules to the `admin`, `edit`, or `view` roles, create +a ClusterRole with one or more of the following labels: ```yaml metadata: @@ -541,32 +660,40 @@ metadata: system:masters group Allows super-user access to perform any action on any resource. When used in a ClusterRoleBinding, it gives full control over every resource in the cluster and in all namespaces. -When used in a RoleBinding, it gives full control over every resource in the rolebinding's namespace, including the namespace itself. +When used in a RoleBinding, it gives full control over every resource in the role binding's namespace, including the namespace itself. admin None Allows admin access, intended to be granted within a namespace using a RoleBinding. If used in a RoleBinding, allows read/write access to most resources in a namespace, -including the ability to create roles and rolebindings within the namespace. -It does not allow write access to resource quota or to the namespace itself. +including the ability to create roles and role bindings within the namespace. +This role does not allow write access to resource quota or to the namespace itself. edit None Allows read/write access to most objects in a namespace. -It does not allow viewing or modifying roles or rolebindings. + +This role does not allow viewing or modifying roles or role bindings. +However, this role allows accessing Secrets and running Pods as any ServiceAccount in +the namespace, so it can be used to gain the API access levels of any ServiceAccount in +the namespace. view None Allows read-only access to see most objects in a namespace. -It does not allow viewing roles or rolebindings. -It does not allow viewing secrets, since those are escalating. +It does not allow viewing roles or role bindings. + +This role does not allow viewing Secrets, since reading +the contents of Secrets enables access to ServiceAccount credentials +in the namespace, which would allow API access as any ServiceAccount +in the namespace (a form of privilege escalation). -### Core Component Roles +### Core component roles @@ -578,7 +705,7 @@ It does not allow viewing secrets, since those are escalating. - + @@ -588,28 +715,27 @@ It does not allow viewing secrets, since those are escalating. - + - - + - +
system:kube-scheduler system:kube-scheduler userAllows access to the resources required by the kube-scheduler component.Allows access to the resources required by the {{< glossary_tooltip term_id="kube-scheduler" text="scheduler" >}} component.
system:volume-scheduler
system:kube-controller-manager system:kube-controller-manager userAllows access to the resources required by the kube-controller-manager component. -The permissions required by individual control loops are contained in the controller roles.Allows access to the resources required by the {{< glossary_tooltip term_id="kube-controller-manager" text="controller manager" >}} component. +The permissions required by individual controllers are detailed in the controller roles.
system:nodeNone in 1.8+Allows access to resources required by the kubelet component, including read access to all secrets, and write access to all pod status objects. +NoneAllows access to resources required by the kubelet, including read access to all secrets, and write access to all pod status objects. -As of 1.7, use of the Node authorizer and NodeRestriction admission plugin is recommended instead of this role, and allow granting API access to kubelets based on the pods scheduled to run on them. -Prior to 1.7, this role was automatically bound to the `system:nodes` group. -In 1.7, this role was automatically bound to the `system:nodes` group if the `Node` authorization mode is not enabled. -In 1.8+, no binding is automatically created. +You should use the Node authorizer and NodeRestriction admission plugin instead of the system:node role, and allow granting API access to kubelets based on the Pods scheduled to run on them. + +The system:node role only exists for compatibility with Kubernetes clusters upgraded from versions prior to v1.8.
system:node-proxier system:kube-proxy userAllows access to the resources required by the kube-proxy component.Allows access to the resources required by the {{< glossary_tooltip term_id="kube-proxy" text="kube-proxy" >}} component.
-### Other Component Roles +### Other component roles @@ -627,7 +753,7 @@ This is commonly used by add-on API servers for unified authentication and autho - + @@ -648,7 +774,7 @@ This is commonly used by add-on API servers for unified authentication and autho +kubelet TLS bootstrapping. @@ -662,73 +788,80 @@ This is commonly used by add-on API servers for unified authentication and autho
system:heapster NoneRole for the Heapster component.Role for the Heapster component (deprecated).
system:kube-aggregatorsystem:node-bootstrapper None Allows access to the resources required to perform -Kubelet TLS bootstrapping.
system:node-problem-detector
-### Controller Roles +### Roles for built-in controllers {#controller-roles} -The [Kubernetes controller manager](/docs/admin/kube-controller-manager/) runs core control loops. -When invoked with `--use-service-account-credentials`, each control loop is started using a separate service account. -Corresponding roles exist for each control loop, prefixed with `system:controller:`. -If the controller manager is not started with `--use-service-account-credentials`, -it runs all control loops using its own credential, which must be granted all the relevant roles. +The Kubernetes {{< glossary_tooltip term_id="kube-controller-manager" text="controller manager" >}} runs +{{< glossary_tooltip term_id="controller" text="controllers" >}} that are built in to the Kubernetes +control plane. +When invoked with `--use-service-account-credentials`, kube-controller-manager starts each controller +using a separate service account. +Corresponding roles exist for each built-in controller, prefixed with `system:controller:`. +If the controller manager is not started with `--use-service-account-credentials`, it runs all control loops +using its own credential, which must be granted all the relevant roles. These roles include: -* system:controller:attachdetach-controller -* system:controller:certificate-controller -* system:controller:clusterrole-aggregation-controller -* system:controller:cronjob-controller -* system:controller:daemon-set-controller -* system:controller:deployment-controller -* system:controller:disruption-controller -* system:controller:endpoint-controller -* system:controller:expand-controller -* system:controller:generic-garbage-collector -* system:controller:horizontal-pod-autoscaler -* system:controller:job-controller -* system:controller:namespace-controller -* system:controller:node-controller -* system:controller:persistent-volume-binder -* system:controller:pod-garbage-collector -* system:controller:pv-protection-controller -* system:controller:pvc-protection-controller -* system:controller:replicaset-controller -* system:controller:replication-controller -* system:controller:resourcequota-controller -* system:controller:root-ca-cert-publisher -* system:controller:route-controller -* system:controller:service-account-controller -* system:controller:service-controller -* system:controller:statefulset-controller -* system:controller:ttl-controller +* `system:controller:attachdetach-controller` +* `system:controller:certificate-controller` +* `system:controller:clusterrole-aggregation-controller` +* `system:controller:cronjob-controller` +* `system:controller:daemon-set-controller` +* `system:controller:deployment-controller` +* `system:controller:disruption-controller` +* `system:controller:endpoint-controller` +* `system:controller:expand-controller` +* `system:controller:generic-garbage-collector` +* `system:controller:horizontal-pod-autoscaler` +* `system:controller:job-controller` +* `system:controller:namespace-controller` +* `system:controller:node-controller` +* `system:controller:persistent-volume-binder` +* `system:controller:pod-garbage-collector` +* `system:controller:pv-protection-controller` +* `system:controller:pvc-protection-controller` +* `system:controller:replicaset-controller` +* `system:controller:replication-controller` +* `system:controller:resourcequota-controller` +* `system:controller:root-ca-cert-publisher` +* `system:controller:route-controller` +* `system:controller:service-account-controller` +* `system:controller:service-controller` +* `system:controller:statefulset-controller` +* `system:controller:ttl-controller` -## Privilege Escalation Prevention and Bootstrapping +## Privilege escalation prevention and bootstrapping The RBAC API prevents users from escalating privileges by editing roles or role bindings. Because this is enforced at the API level, it applies even when the RBAC authorizer is not in use. -A user can only create/update a role if at least one of the following things is true: +### Restrictions on role creation or update -1. They already have all the permissions contained in the role, at the same scope as the object being modified -(cluster-wide for a `ClusterRole`, within the same namespace or cluster-wide for a `Role`) -2. They are given explicit permission to perform the `escalate` verb on the `roles` or `clusterroles` resource in the `rbac.authorization.k8s.io` API group (Kubernetes 1.12 and newer) +You can only create/update a role if at least one of the following things is true: -For example, if "user-1" does not have the ability to list secrets cluster-wide, they cannot create a `ClusterRole` +1. You already have all the permissions contained in the role, at the same scope as the object being modified +(cluster-wide for a ClusterRole, within the same namespace or cluster-wide for a Role). +2. You are granted explicit permission to perform the `escalate` verb on the `roles` or `clusterroles` resource in the `rbac.authorization.k8s.io` API group. + +For example, if `user-1` does not have the ability to list Secrets cluster-wide, they cannot create a ClusterRole containing that permission. To allow a user to create/update roles: -1. Grant them a role that allows them to create/update `Role` or `ClusterRole` objects, as desired. -2. Grant them permission to include specific permissions in the roles the create/update: - * implicitly, by giving them those permissions (if they attempt to create or modify a `Role` or `ClusterRole` with permissions they themselves have not been granted, the API request will be forbidden) - * or explicitly allow specifying any permission in a `Role` or `ClusterRole` by giving them permission to perform the `escalate` verb on `roles` or `clusterroles` resources in the `rbac.authorization.k8s.io` API group (Kubernetes 1.12 and newer) +1. Grant them a role that allows them to create/update Role or ClusterRole objects, as desired. +2. Grant them permission to include specific permissions in the roles they create/update: + * implicitly, by giving them those permissions (if they attempt to create or modify a Role or ClusterRole with permissions they themselves have not been granted, the API request will be forbidden) + * or explicitly allow specifying any permission in a `Role` or `ClusterRole` by giving them permission to perform the `escalate` verb on `roles` or `clusterroles` resources in the `rbac.authorization.k8s.io` API group -A user can only create/update a role binding if they already have all the permissions contained in the referenced role -(at the same scope as the role binding) *or* if they've been given explicit permission to perform the `bind` verb on the referenced role. -For example, if "user-1" does not have the ability to list secrets cluster-wide, they cannot create a `ClusterRoleBinding` +### Restrictions on role binding creation or update + +You can only create/update a role binding if you already have all the permissions contained in the referenced role +(at the same scope as the role binding) *or* if you have been authorized to perform the `bind` verb on the referenced role. +For example, if `user-1` does not have the ability to list Secrets cluster-wide, they cannot create a ClusterRoleBinding to a role that grants that permission. To allow a user to create/update role bindings: -1. Grant them a role that allows them to create/update `RoleBinding` or `ClusterRoleBinding` objects, as desired. +1. Grant them a role that allows them to create/update RoleBinding or ClusterRoleBinding objects, as desired. 2. Grant them permissions needed to bind a particular role: * implicitly, by giving them the permissions contained in the role. - * explicitly, by giving them permission to perform the `bind` verb on the particular role (or cluster role). + * explicitly, by giving them permission to perform the `bind` verb on the particular Role (or ClusterRole). -For example, this cluster role and role binding would allow "user-1" to grant other users the `admin`, `edit`, and `view` roles in the "user-1-namespace" namespace: +For example, this ClusterRole and RoleBinding would allow `user-1` to grant other users the `admin`, `edit`, and `view` roles in the namespace `user-1-namespace`: ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -762,126 +895,126 @@ subjects: When bootstrapping the first roles and role bindings, it is necessary for the initial user to grant permissions they do not yet have. To bootstrap initial roles and role bindings: -* Use a credential with the `system:masters` group, which is bound to the `cluster-admin` super-user role by the default bindings. +* Use a credential with the "system:masters" group, which is bound to the "cluster-admin" super-user role by the default bindings. * If your API server runs with the insecure port enabled (`--insecure-port`), you can also make API calls via that port, which does not enforce authentication or authorization. -## Command-line Utilities +## Command-line utilities ### `kubectl create role` -Creates a `Role` object defining permissions within a single namespace. Examples: +Creates a Role object defining permissions within a single namespace. Examples: -* Create a `Role` named "pod-reader" that allows user to perform "get", "watch" and "list" on pods: +* Create a Role named "pod-reader" that allows users to perform `get`, `watch` and `list` on pods: - ``` + ```shell kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods ``` -* Create a `Role` named "pod-reader" with resourceNames specified: +* Create a Role named "pod-reader" with resourceNames specified: - ``` + ```shell kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod ``` -* Create a `Role` named "foo" with apiGroups specified: +* Create a Role named "foo" with apiGroups specified: - ``` + ```shell kubectl create role foo --verb=get,list,watch --resource=replicasets.apps ``` -* Create a `Role` named "foo" with subresource permissions: +* Create a Role named "foo" with subresource permissions: - ``` + ```shell kubectl create role foo --verb=get,list,watch --resource=pods,pods/status ``` -* Create a `Role` named "my-component-lease-holder" with permissions to get/update a resource with a specific name: +* Create a Role named "my-component-lease-holder" with permissions to get/update a resource with a specific name: - ``` + ```shell kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-component ``` ### `kubectl create clusterrole` -Creates a `ClusterRole` object. Examples: +Creates a ClusterRole. Examples: -* Create a `ClusterRole` named "pod-reader" that allows user to perform "get", "watch" and "list" on pods: +* Create a ClusterRole named "pod-reader" that allows user to perform `get`, `watch` and `list` on pods: - ``` + ```shell kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods ``` -* Create a `ClusterRole` named "pod-reader" with resourceNames specified: +* Create a ClusterRole named "pod-reader" with resourceNames specified: - ``` + ```shell kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod ``` -* Create a `ClusterRole` named "foo" with apiGroups specified: +* Create a ClusterRole named "foo" with apiGroups specified: - ``` + ```shell kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps ``` -* Create a `ClusterRole` named "foo" with subresource permissions: +* Create a ClusterRole named "foo" with subresource permissions: - ``` + ```shell kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status ``` -* Create a `ClusterRole` name "foo" with nonResourceURL specified: +* Create a ClusterRole named "foo" with nonResourceURL specified: - ``` + ```shell kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/* ``` -* Create a `ClusterRole` name "monitoring" with aggregationRule specified: +* Create a ClusterRole named "monitoring" with an aggregationRule specified: - ``` + ```shell kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true" ``` ### `kubectl create rolebinding` -Grants a `Role` or `ClusterRole` within a specific namespace. Examples: +Grants a Role or ClusterRole within a specific namespace. Examples: -* Within the namespace "acme", grant the permissions in the `admin` `ClusterRole` to a user named "bob": +* Within the namespace "acme", grant the permissions in the "admin" ClusterRole to a user named "bob": - ``` + ```shell kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme ``` -* Within the namespace "acme", grant the permissions in the `view` `ClusterRole` to the service account in the namespace "acme" named "myapp" : +* Within the namespace "acme", grant the permissions in the "view" ClusterRole to the service account in the namespace "acme" named "myapp": - ``` + ```shell kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme ``` -* Within the namespace "acme", grant the permissions in the `view` `ClusterRole` to a service account in the namespace "myappnamespace" named "myapp": +* Within the namespace "acme", grant the permissions in the "view" ClusterRole to a service account in the namespace "myappnamespace" named "myapp": - ``` + ```shell kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme ``` ### `kubectl create clusterrolebinding` -Grants a `ClusterRole` across the entire cluster, including all namespaces. Examples: +Grants a ClusterRole across the entire cluster (all namespaces). Examples: -* Across the entire cluster, grant the permissions in the `cluster-admin` `ClusterRole` to a user named "root": +* Across the entire cluster, grant the permissions in the "cluster-admin" ClusterRole to a user named "root": - ``` + ```shell kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root ``` -* Across the entire cluster, grant the permissions in the `system:node-proxier ` `ClusterRole` to a user named "system:kube-proxy": +* Across the entire cluster, grant the permissions in the "system:node-proxier" ClusterRole to a user named "system:kube-proxy": - ``` + ```shell kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy ``` -* Across the entire cluster, grant the permissions in the `view` `ClusterRole` to a service account named "myapp" in the namespace "acme": +* Across the entire cluster, grant the permissions in the "view" ClusterRole to a service account named "myapp" in the namespace "acme": - ``` + ```shell kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp ``` @@ -901,33 +1034,32 @@ Examples: * Test applying a manifest file of RBAC objects, displaying changes that would be made: - ``` + ```shell kubectl auth reconcile -f my-rbac-rules.yaml --dry-run ``` * Apply a manifest file of RBAC objects, preserving any extra permissions (in roles) and any extra subjects (in bindings): - ``` + ```shell kubectl auth reconcile -f my-rbac-rules.yaml ``` * Apply a manifest file of RBAC objects, removing any extra permissions (in roles) and any extra subjects (in bindings): - ``` + ```shell kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions ``` -See the CLI help for detailed usage. - -## Service Account Permissions +## ServiceAccount permissions {#service-account-permissions} Default RBAC policies grant scoped permissions to control-plane components, nodes, and controllers, but grant *no permissions* to service accounts outside the `kube-system` namespace (beyond discovery permissions given to all authenticated users). -This allows you to grant particular roles to particular service accounts as needed. +This allows you to grant particular roles to particular ServiceAccounts as needed. Fine-grained role bindings provide greater security, but require more effort to administrate. -Broader grants can give unnecessary (and potentially escalating) API access to service accounts, but are easier to administrate. +Broader grants can give unnecessary (and potentially escalating) API access to +ServiceAccounts, but are easier to administrate. In order from most secure to least secure, the approaches are: @@ -949,9 +1081,10 @@ In order from most secure to least secure, the approaches are: If an application does not specify a `serviceAccountName`, it uses the "default" service account. - {{< note >}}Permissions given to the "default" service - account are available to any pod in the namespace that does not - specify a `serviceAccountName`.{{< /note >}} + {{< note >}} + Permissions given to the "default" service account are available to any pod + in the namespace that does not specify a `serviceAccountName`. + {{< /note >}} For example, grant read-only permission within "my-namespace" to the "default" service account: @@ -962,12 +1095,15 @@ In order from most secure to least secure, the approaches are: --namespace=my-namespace ``` - Many [add-ons](/docs/concepts/cluster-administration/addons/) currently run as the "default" service account in the `kube-system` namespace. - To allow those add-ons to run with super-user access, grant cluster-admin permissions to the "default" service account in the `kube-system` namespace. + Many [add-ons](/docs/concepts/cluster-administration/addons/) run as the + "default" service account in the `kube-system` namespace. + To allow those add-ons to run with super-user access, grant cluster-admin + permissions to the "default" service account in the `kube-system` namespace. - {{< note >}}Enabling this means the `kube-system` - namespace contains secrets that grant super-user access to the - API.{{< /note >}} + {{< caution >}} + Enabling this means the `kube-system` namespace contains Secrets + that grant super-user access to your cluster's API. + {{< /caution >}} ```shell kubectl create clusterrolebinding add-on-cluster-admin \ @@ -1006,9 +1142,9 @@ In order from most secure to least secure, the approaches are: If you don't care about partitioning permissions at all, you can grant super-user access to all service accounts. {{< warning >}} - This allows any user with read access - to secrets or the ability to create a pod to access super-user - credentials. + This allows any application full access to your cluster, and also grants + any user with read access to Secrets (or the ability to create any pod) + full access to your cluster. {{< /warning >}} ```shell @@ -1017,10 +1153,11 @@ In order from most secure to least secure, the approaches are: --group=system:serviceaccounts ``` -## Upgrading from 1.5 +## Upgrading from ABAC -Prior to Kubernetes 1.6, many deployments used very permissive ABAC policies, -including granting full API access to all service accounts. +Clusters that originally ran older Kubernetes versions often used +permissive ABAC policies, including granting full API access to all +service accounts. Default RBAC policies grant scoped permissions to control-plane components, nodes, and controllers, but grant *no permissions* to service accounts outside the `kube-system` namespace @@ -1029,28 +1166,31 @@ and controllers, but grant *no permissions* to service accounts outside the `kub While far more secure, this can be disruptive to existing workloads expecting to automatically receive API permissions. Here are two approaches for managing this transition: -### Parallel Authorizers +### Parallel authorizers Run both the RBAC and ABAC authorizers, and specify a policy file that contains -[the legacy ABAC policy](/docs/reference/access-authn-authz/abac/#policy-file-format): +the [legacy ABAC policy](/docs/reference/access-authn-authz/abac/#policy-file-format): ``` ---authorization-mode=RBAC,ABAC --authorization-policy-file=mypolicy.json +--authorization-mode=...,RBAC,ABAC --authorization-policy-file=mypolicy.json ``` -The RBAC authorizer will attempt to authorize requests first. If it denies an API request, -the ABAC authorizer is then run. This means that any request allowed by *either* the RBAC -or ABAC policies is allowed. +To explain that first command line option in detail: if earlier authorizers, such as Node, +deny a request, then the the RBAC authorizer attempts to authorize the API request. If RBAC +also denies that API request, the ABAC authorizer is then run. This means that any request +allowed by *either* the RBAC or ABAC policies is allowed. -When the apiserver is run with a log level of 5 or higher for the RBAC component (`--vmodule=rbac*=5` or `--v=5`), -you can see RBAC denials in the apiserver log (prefixed with `RBAC DENY:`). +When the kube-apiserver is run with a log level of 5 or higher for the RBAC component +(`--vmodule=rbac*=5` or `--v=5`), you can see RBAC denials in the API server log +(prefixed with `RBAC DENY:`). You can use that information to determine which roles need to be granted to which users, groups, or service accounts. -Once you have [granted roles to service accounts](#service-account-permissions) and workloads are running with no RBAC denial messages -in the server logs, you can remove the ABAC authorizer. -## Permissive RBAC Permissions +Once you have [granted roles to service accounts](#service-account-permissions) and workloads +are running with no RBAC denial messages in the server logs, you can remove the ABAC authorizer. -You can replicate a permissive policy using RBAC role bindings. +### Permissive RBAC permissions + +You can replicate a permissive ABAC policy using RBAC role bindings. {{< warning >}} The following policy allows **ALL** service accounts to act as cluster administrators. @@ -1058,7 +1198,7 @@ Any application running in a container receives service account credentials auto and could perform any action against the API, including viewing secrets and modifying permissions. This is not a recommended policy. -``` +```shell kubectl create clusterrolebinding permissive-binding \ --clusterrole=cluster-admin \ --user=admin \ @@ -1067,4 +1207,7 @@ kubectl create clusterrolebinding permissive-binding \ ``` {{< /warning >}} +After you have transitioned to use RBAC, you should adjust the access controls +for your cluster to ensure that these meet your information security needs. + {{% /capture %}}