Trending keywords: security, cloud, container,
Kubernetes is not a security platform. It lacks native tooling to handle most security-related tasks, such as detecting vulnerabilities within applications and monitoring for breaches.
However, there is one security task that Kubernetes does handle very well in a native way: role-based access control (RBAC). Kubernetes offers an extensive, built-in RBAC framework. Taking advantage of Kubernetes RBAC is a basic first step toward securing clusters and applications running in Kubernetes.
This article walks through the concepts that are at the core of Kubernetes RBAC, demonstrates how to use Kubernetes RBAC policies, and highlights best practices to follow and mistakes to avoid when working with RBAC in Kubernetes.
Kubernetes RBAC: Fundamental Concepts
If you’re reading this, you’re probably familiar with RBAC as a general principle. In a variety of contexts (such as operating systems and public clouds), RBAC systems can be used to define who can access what based on user identities.
Kubernetes RBAC builds on these concepts. However, RBAC in Kubernetes is different in a few key ways from most other types of RBAC frameworks:
User Accounts vs. Service Accounts
In Kubernetes, RBAC policies can be used to define the access rights of human users (or groups of human users). Kubernetes identifies human users as user accounts.
However, RBAC policies can also govern the behavior of software resources, which Kubernetes identifies as service accounts.
Although Kubernetes draws a distinction between user accounts and service accounts at a conceptual level, the difference doesn’t really matter as far as RBAC policies are concerned. This makes Kubernetes RBAC different from many other RBAC systems, which usually focus on managing the permissions of human users (based on factors like their job role or account type) rather than managing access for software services.
Flexible Resource Definitions
Kubernetes RBAC is also quite broad when it comes to the way that Kubernetes defines the entities that RBAC policies can govern.
Kubernetes refers to these entities as “resources,” and they can be almost anything you want them to be: pods, logs, ingress controllers, or any other type of custom resource you choose to define.
Most other RBAC systems tend to be more restrictive about the types of resources you can manage. For example, cloud IAM frameworks are designed to manage just predefined types of resources, like virtual machine instances or storage buckets. (You may be able to use tagging, too, to control which policies apply to which resources, but this is less scalable than Kubernetes’s approach because you would have to create each tag manually.)
Roles vs. ClusterRoles
A relatively simple but important peculiarity of Kubernetes RBAC is that it draws a distinction between permissions that apply to resources within one namespace, which are managed through Roles, and those that apply to the entire cluster, which are managed through ClusterRoles.
In most cases, you’ll work with Roles, which can be used to manage permissions on a more granular basis (i.e., within individual namespaces). But sometimes, you’ll want to use ClusterRoles to manage rules for resources that only exist at the cluster level, like Kubernetes nodes.
Managing Permissions Through “Verbs”
Unlike access control systems that can only allow or deny access, or systems that break access rights into broad categories like “read,” “write,” and “execute,” Kubernetes RBAC provides a series of “verbs” that define the specific actions that accounts can perform on resources.
For example, you can allow a user to “create” and “list” a given resource by specifying the appropriate verbs within an RBAC policy.
You can get a list of all of the available verbs in your cluster by running:
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -l <label>=<value> -n <namespace>Code language: HTML, XML (xml)
Working with Kubernetes RBAC: Steps and Examples
Now that we know the fundamentals of RBAC in Kubernetes, let’s look at how to use it.
Check for RBAC Support
First, make sure that your cluster supports RBAC. RBAC was introduced with Kubernetes 1.6, and most clusters enable it by default, but it never hurts to check.
Look for a RBAC configuration file in /etc/kubernetes/manifests on your master node(s) or the Kubernetes API server pod, and make sure it contains the flag:
Define Users and Service Accounts
Next, you need to define users and/or service accounts, to which you’ll later assign permissions. As a simple example, here are the steps for creating a user account for a user whom we’ll name John.
Start by creating a new private key:
openssl genrsa -out john.key 2048Code language: CSS (css)
Then, you need to create a certificate signing request containing the public key and other
openssl req -new -key john.key -out john.csr -subj "/CN=john/ O=examplegroup"Code language: PHP (php)
Note that Kubernetes will use the Organization (O=examplegroup) field to determine user
group membership for RBAC.
You will sign this CSR using the root Kubernetes CA, found in /etc/kubernetes/pki for this example (the file location in your deployment may vary):
You can inspect the new certificate:
openssl x509 -in john.crt -text Certificate: Data: Version: 1 (0x0) Serial Number: 11309651818125161147 (0x9cf3f46850b372bb) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=kubernetes Validity Not Before: Apr 2 20:20:54 2018 GMT Not After : May 2 20:20:54 2018 GMT Subject: CN=john, O=examplegroup Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit)Code language: PHP (php)
Finally, register the new credentials and config context:
Create a Role or ClusterRole
Next, we need to create a Role or ClusterRole. This is where we define the actions that can be performed on a resource.
For example, here is a role that grants get, watch, and list permissions for 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"]Code language: PHP (php)
Create a RoleBinding or ClusterRoleBinding
Finally, we have to “bind” our Role or ClusterRole to the user or account we created. The binding is what actually allows the specified user or account to perform the given role.
kubectl create rolebinding podreader-binding --user=john
Kubernetes RBAC Best Practices
Kubernetes RBAC is a powerful tool. The following are best practices for using it as responsibly as possible.
Minimize API Server Flags
The Kubernetes API has a number of optional flags that, when enabled, may simplify some aspects of Kubernetes management. But they also heighten security risks. Avoid these flags whenever possible:
- –insecure-port: Opens up access to unauthorized, unauthenticated requests. If this
- parameter is equal to 0, it means no insecure port.
- –insecure-bind-address: Ideally, you should avoid insecure connections altogether, but in case you really need them, you can use this parameter to just bind to localhost. Make sure this parameter is not set, or at least not set to a network-reachable IP address.
- –anonymous-auth: Enables anonymous requests to the secure port of the API server.
Follow Least Privilege
As with any RBAC system, Kubernetes RBAC is most effective when admins follow the principle of least privilege, which means that each user or account receives only the minimum privileges necessary to perform their job.
In practice, this means doing things like using Roles instead of ClusterRoles wherever possible. Even though setting up Roles for each namespace is a bit more cumbersome than being able to define a ClusterRole to the entire cluster, Roles are more secure because they apply to fewer resources.
Likewise, avoid wildcards [“*”] when you define verbs or access to resources. Wildcards are the “chmod 777” of Kubernetes: they’re convenient to apply, but they open up all sorts of unauthorized access holes.
Avoid Default Service Accounts
Kubernetes creates default service accounts to identify the processes running in a pod.
You may be tempted to use these default accounts to assign permissions rather than going to the trouble of setting up your own accounts. That’s not a best practice. Instead, create service-specific service accounts, which provide the foundation for more granular access controls.
By the way, if you’re wondering about default users, Kubernetes doesn’t have default user accounts, so you don’t need to worry about those. You have to create users explicitly if you want to assign Roles or ClusterRoles to them.
Update RBAC Policies Continuously
Kubernetes RBAC is only as effective as the RBAC policies you create. And if your policies become outdated, you may quickly end up with users or service accounts that are over-permissioned.
For that reason, it’s a best practice to ensure that whenever you create, remove, or update the permissions of any user or service account, or when you create a namespace or pods, you also modify or delete all RBAC policies associated with that entity. This can be somewhat tedious, given that Kubernetes has multiple types of files associated with RBAC (Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings). Still, it’s important to make RBAC policy updates a systematic and continuous part of Kubernetes management.
Making the Most of Kubernetes RBAC
It’s impossible to run a secure Kubernetes cluster of any size without taking advantage of RBAC. While you may be able to get by without RBAC policies if you’re running a single-node cluster on your laptop for testing purposes, a cluster with multiple users, pods, namespaces, and the like needs RBAC policies to define who and what can do what within the cluster.
Thus, although Kubernetes’s approach to RBAC may feel a little unusual in certain respects, and it’s not always the simplest type of RBAC system to work with, investing time in understanding how RBAC in Kubernetes works and how to use it effectively is a basic best practice for securing any production Kubernetes environment.