Kubernetes RBAC makes authorization an API operation
The Kubernetes 1.6 RBAC guidance explains how roles and bindings replace authorization files on the master. Running RBAC beside permissive ABAC leaves the old permissions effective.
Changing who can operate a cluster should not require changing a file as root on its master and restarting the API server. That is the operational problem behind the April 6 RBAC guidance. Kubernetes' ABAC implementation requires those steps for policy changes. RBAC moves the policy into Kubernetes API objects, so administrators can change it with kubectl or another API client.
The change matters beyond convenience. Access to the master's filesystem grants a different kind of authority from permission to manage a particular application's resources. An API-based authorization model makes it possible to delegate some policy administration without also delegating SSH access to the machine. It also gives authorization policy a representation alongside the objects whose use it controls.
I regard that alignment as a substantial improvement to Kubernetes' administrative model. The API already defines the resources an application can manipulate. Expressing permissions in the same terms makes the relationship between an operation and the authority needed for it easier to inspect.
Roles describe permission and bindings assign it
A Role contains a collection of permissions. A RoleBinding connects those permissions to subjects, such as users or service accounts, within a namespace. ClusterRole and ClusterRoleBinding provide the corresponding cluster-level objects. The separation lets several subjects share a definition of permitted operations without placing their identities inside every rule.
The 1.6 beta API definitions make the scope precise. A RoleBinding can reference a Role in its own namespace or a ClusterRole. Its effect remains confined to the namespace containing the binding. Referencing a ClusterRole does not turn that RoleBinding into a grant across the whole cluster.
For example, these objects allow an existing observer service account to get and list Pods in the existing payments namespace. The beta API version is the version discussed in the April guidance.
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: pod-reader
namespace: payments
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: observer-pod-reader
namespace: payments
subjects:
- kind: ServiceAccount
name: observer
namespace: payments
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
The empty API group identifies the core API resources. The rule grants the two named verbs on Pods, and the binding selects the account that receives them. It does not grant permission to modify Pods or read Secrets. Creating the service account and namespace remains separate from creating this grant.
This distinction is useful for applications that call Kubernetes themselves. Jenkins with its Kubernetes plugin and Helm are examples named in the guidance. Their ability to operate depends on API permissions just as kubectl's ability does. Running inside the cluster does not by itself define the appropriate scope of those permissions.
A mounted token is not a grant of authority
The guidance identifies service accounts as the most likely source of application disruption during an ABAC-to-RBAC transition. Under permissive ABAC policies, a Pod using its mounted service-account token may have broad access. RBAC's default system permissions are narrower. An application can continue to present a valid token while an operation that used to succeed now receives an authorization error.
The article demonstrates the difference by issuing an API request to list Pods from inside a container. Its point is the authorization result, not a change in how the application discovers the API server. The identity presented by the request can remain the same while the permission decision changes. That separates authentication from the decision to permit a particular operation.
An application's actual Kubernetes dependency therefore includes the resources and verbs it uses. An installer that merely obtains a token has not established that the application can perform its work. A controller that lists Pods needs an appropriate grant, while a component that does not call the API need not receive broad authority simply because it runs in a Pod.
Two authorizers can preserve the old access
Kubernetes 1.6 allows a cluster to enable ABAC and RBAC together during transition. The request succeeds if either authorizer grants it. This can ease migration because an incomplete RBAC policy does not immediately remove access that ABAC still permits. It also limits what can be concluded from a successful request.
Adding a narrowly scoped RBAC Role does not cancel a broader ABAC grant. If ABAC still authorizes the operation, the combined configuration permits it. The April guidance explicitly warns that RBAC cannot fully control permissions in that arrangement. A policy declaration that looks restrictive is not evidence of restriction while another enabled authorizer supplies the missing permission.
My preference is for permission decisions that can be explained from the configured policies. The transition mode requires that explanation to include both authorizers. Its value is continuity while permissions are being described, and its limitation is that continued success cannot prove the RBAC description is sufficient.
The system roles now cover the permissions needed to run Kubernetes with RBAC alone. Their system: prefixes identify many of the built-in grants. The project describes development attention as focused on RBAC while ABAC remains available for the foreseeable future. For an application owner, the practical consequence is a more explicit dependency on named API operations, with that dependency represented in Roles and bindings that can be changed through the cluster API.