In this article, we will explore configuring role-based access control (RBAC) for Amazon Elastic Kubernetes Service (EKS). Amazon EKS is Amazon's managed Kubernetes service that makes it easy for you to run Kubernetes on AWS and on-premises. EKS has many large customers, and it’s become the preferred way of running Kubernetes in EKS. Amazon EKS Anywhere lets teams create and operate Kubernetes clusters on your own infrastructure. As teams have adopted Kubernetes, they quickly need to set up role-based access control (RBAC) to limit who can access which pods, namespace, users and roles.
This post will provide a range of options for RBAC for EKS, with practical guides for using open-source Teleport to provide RBAC for both clouds and on-premises EKS clusters.
Prerequisites: This article assumes that you have deployed a Teleport cluster and an EKS cluster, either with your EKS cluster via our helm chart or connected via Teleport Cloud. If you don’t have an EKS cluster, we recommend using `eksctl` to create the appropriate resources.
Role-based access control is a method of regulating access to resources based on the roles of an individual user. For example, the DevOps team may need full access to Kubernetes, but software engineering might only have access to pods in the development namespace. RBAC is often combined with a central IDP and SSO provider, such as Okta, ActiveDirectory or GitHub. These IDPs often contain extra metadata, such as groups. These groups are often used in combination with IDPs.
The core logical components of RBAC are:
There are two types of Roles (Role, ClusterRole) and their respective bindings (RoleBinding, ClusterRoleBinding). These differentiate between authorization in a namespace or cluster-wide. For this article, we’ll be mainly focusing on how end users access a Kubernetes cluster and will focus on Kubernetes groups, users, and namespaces. For the purposes of this tutorial, we’re focused on human operators accessing Kubernetes. If you’re interested in machines / CI/CD interacting with Kubernetes, we recommend using MachineID.
A good way to know what a Kubernetes / kubectl user can currently do is to use `kubectl auth can-i --list`.
$ kubectl auth can-i --list$ kubectl auth can-i create pods --all-namespaces
AWS EKS lets teams use an IAM Principal to access Kubernetes. An IAM principle is an entity that can perform actions and access resources. When creating a EKS cluster, an IAM principal is automatically granted access to the ‘system:masters’ role. This is a highly elevated permission, and we would recommend only using this in a break glass scenario.
Using or sharing an IAM principle can also result in other issues, such as not knowing who’s performing which actions on the cluster, with extra audit logging needed. It’s instead better to map SSO users to Kubernetes using a 3rd party IDP and SSO provider.
Using Single Sign-On (SSO) for accessing the Kubernetes API offers several benefits that can enhance the security and usability of your Kubernetes clusters. Here are some reasons to consider SSO for Kubernetes API access:
While this article is focused on RBAC, we have a complete guide for setting up SSO with EKS.
In this section, we’ll look into authenticating to a Kubernetes cluster via Teleport; your Teleport roles must allow access as at least one Kubernetes user or group.
Create a ServiceAccount, say 'readonlyuser'.
kubectl create serviceaccount readonlyuser
Create cluster role, say 'readonlyuser'.
kubectl create clusterrole readonlyuser --verb=get --verb=list --verb=watch --resource=pods
Create cluster role binding, say 'readonlyuser'.
kubectl create clusterrolebinding readonlyuser --serviceaccount=default:readonlyuser --clusterrole=readonlyuser
This will create a new read only users that’s only able to watch pods. This is a restricted role.
Create a file called kube-access.yaml with the following content, replacing USER with the output of the command above.
kind: role
metadata:
name: kube-access-readonly
version: v6
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
kubernetes_users:
- readonlyuser
deny: {}
Apply your changes:
tctl create -f kube-access-readonly.yaml
Assign the kube-access role to your Teleport user by running the following commands, depending on whether you authenticate as a local Teleport user or via the GitHub, SAML, or OIDC authentication connectors. See Getting Started With Access Controls. For our example, we'll add `kube-access-readonly` to the user.
Now that Teleport RBAC is configured, you can authenticate to your Kubernetes cluster via Teleport. Log out of Teleport and log in again; when you log in using `tsh kube login` you’ll get a new kubeconfig with the current permissions.
tsh login --proxy=teleport example.com --auth=github
tsh kube login cookie
kubectl version
kubectl get pods
In this section, we’ll set up RBAC that’ll limit access to Kubernetes resources, by limiting access to pods and nodes using Kubernetes namespaces. Note: namespaces are often used as a security boundary, but a Kubernetes namespace is not a security boundary in itself because there are things that are not namespaced, so there is no way to accurately correlate security criteria to the namespace. Learn more about securing Kubernetes from our podcast Hacking Kubernetes - Overview.
Before setting up per-pod RBAC, it’s important to know what namespaces and pods you have within a cluster. `kubectl get pods –all-namespaces` is a helpful command to list all pods within a cluster.
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6f5f9b5d74-7g8rz 1/1 Running 0 14d
kube-system calico-node-4d7fz 1/1 Running 0 14d
ingress nginx-ingress-microk8s-controller-h56nn 0/1 Pending 0 14d
kube-system hostpath-provisioner-69cd9ff5b8-wtqt6 1/1 Running 0 14d
ingress nginx-ingress-microk8s-controller-l7hj5 1/1 Running 0 14d
kube-system calico-node-vkfpl 1/1 Running 0 18d
default shell-demo 1/1 Running 0 14d
kube-system calico-kube-controllers-69f8d4c8f6-2j6dg 0/1 Terminating 0 18d
kube-system calico-kube-controllers-69f8d4c8f6-hz2wf 1/1 Running 0 14d
colormatic colormatic-784db57b6-j7v6p 1/1 Running 0 11d
teleport-agent teleport-agent-0 1/1 Running 0 14d
Next we’ll define a new Teleport Role, kube-access. This role has a few RBAC mechanisms.
Here is a summary of what this role can do:
kind: role
metadata:
name: kube-access
version: v6
spec:
allow:
kubernetes_labels:
'region': '*'
'platform': 'minikube'
kubernetes_resources:
- kind: pod
namespace: "production"
name: "^webapp-[a-z0-9-]+$"
- kind: pod
namespace: "development"
name: "*"
kubernetes_groups:
- developers
kubernetes_users:
- minikube
deny: {}
Create the role using ‘tctl create’.
tctl create kube-access.yaml
Next, we’ll assign this new role to our GitHub SSO connector. In this case, we’ve added ‘kube-acess’ to the `trainee-graviton` group.
kind: github
metadata:
name: github
spec:
client_id: x
client_secret: x
display: github
endpoint_url: https://github.com
redirect_url: https://teleport.example.com:443/v1/webapi/github/callback
teams_to_roles:
- organization: asteroid-earth
roles:
- access
- kube-access
team: trainee-graviton
version: v3
See this documentation page for other options.
The last step is to test the setup. In this case we’ll use GitHub SSO provider via Teleport to obtain a new kubeconfig.
tsh login --proxy=teleport example.com --auth=github
tsh kube login cookie
kubectl version
kubectl get pods
Kubernetes groups are useful for sharing a specific set of permissions for a group. For example, the SRE team can access resources, and Developers can only view deployed pods. When combined with SSO, using external groups and Kubernetes groups, it can greatly simplify the access controls for kubernetes. By using Kubernetes groups in combination with Teleport, teams also get a per-user audit log for actions on the kubectl API or via kubectl execs.
Create a file called viewers-bind.yaml with the following contents:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: viewers-crb
subjects:
- kind: Group
# Bind the group "viewers", corresponding to the kubernetes_groups we assigned our "kube-access" role above
name: viewers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
# "view" is a default ClusterRole that grants read-only access to resources
# See: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
name: view
apiGroup: rbac.authorization.k8s.io
Apply the ClusterRoleBinding with kubectl:
kubectl apply -f viewers-bind.yaml
Next we’ll create a Teleport RBAC mapping. This yaml file is used to provide access to the viewer group above.
kind: role
metadata:
name: kube-access
version: v6
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
kubernetes_groups:
- viewers
kubernetes_users:
- USER
deny: {}
Apply your changes:
tctl create -f kube-access.yaml
The last step is to test the setup. In this case we’ll use GitHub SSO provider via Teleport to obtain a new kubeconfig.
tsh login --proxy=teleport example.com --auth=github
tsh kube login cookie
kubectl version
kubectl get pods
If you’ve followed any of the above guides for setting up Kubernetes RBAC with Teleport, the end flow will look something like this.
tsh login --proxy=teleport example.com --auth=github
tsh kube login cookie
kubectl exec --stdin --tty shell-demo -- /bin/bash
RBAC to Kubernetes dashboard
Along with the underlying Kubernetes API, it’s important to secure any apps or admins tools such as the Kubernetes dashboard that also run in Kubernetes.
Under the section `Map IAM roles to Kubernetes` we discussed that using an IAM user defaults to the ‘system:masters’ role. We recommend using a SSO for your AWS account and AWS CLI command line tool to improve auditing and access to that role. Teleport Application Access lets teams share a AWS IAM role arn between users.
We cover this topic in more detail in this post Access AWS With Teleport Application Access.
This article has covered three main areas that you may consider for Kubernetes RBAC for teams accessing k8s: providing access to Kubernetes Users, Groups and Per-Pod RBAC. The examples highlight the capabilities of Teleport. Try Teleport Team for 14 days free.
Other related posts: