RBAC WALKTHROUGH: Using an IAM group to assign permission to the Kubernetes API

Jeremy Cowan
3 min readSep 5, 2019

--

Introduction

This walkthrough explains how to create an AWS role that members of an IAM group can assume. The assumed role is then mapped to a Kubernetes RBAC role in the aws-auth ConfigMap which allows the group members to perform a set of actions against the Kubernetes API, e.g. patch, get, create, etc.

As an alternative to assuming an IAM role, you can use the group-operator. The group-operator is a Kubernetes operator that enumerates the members of an IAM group and add/removes them from the aws-auth ConfigMap automatically.

Create a cluster role

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:

  • 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)

This role grants the ability to read pods in all namespaces.

cat << 'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-reader-cr
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
EOF

Create a role binding

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.

cat << 'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-rb
namespace: default
subjects:
- kind: Group
name: pod-reader # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-reader-cr
apiGroup: rbac.authorization.k8s.io
EOF

Create IAM role

Create trust policy document

Allows all users from an AWS account to assume this role.

cat > [filename] << 'EOF' 
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:root" },
"Action": "sts:AssumeRole"
}
}
EOF

Create an IAM role

Binds the trust policy to the IAM role.

ROLE_ARN=$(aws iam create-role --role-name pod-reader-role --assume-role-policy-document file://[filename] | jq -r '.Role.Arn')

Create IAM group

aws iam create-group --group-name [group_name]

Create IAM policy document

cat > [filename] << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "123",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::123456789012:role/pod-reader-role"
]
}
]
}
EOF

Create Assume role POLICY

POLICY_ARN=$(aws iam create-policy --policy-name [policy_name] --policy-document file://[filename] | jq -r '.Policy.Arn')

Attach assume role policy to group

When the policy is attached to the group, it allows members of the group to assume an IAM role. This role is mapped to the pod-reader Kubernetes RBAC group which allows users to get and list pods in the default namespace.

aws iam attach-group-policy --group-name [group_name] --policy-arn $POLICY_ARN

Add IAM users to group

aws iam add-user-to-group --group-name [group_name] --user-name [user_name]

Update aws-auth configmap

Creates a mapping between the IAM role and the Kubernetes RBAC group pod-reader.

ROLE="    - userarn: $ROLE_ARN\n      username: pod-reader\n      groups:\n        - pod-reader"
kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapUsers: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.yml
kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)"

Update kubeconfig

Adding the --role flag to the arguments passed to the AWS CLI will generate a token for specific IAM role that gets passed to the Kubernetes API when the user issues kubectl commands.

- name: [context_name]
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- eks
- get-token
- --cluster-name
- [cluster_name]
- --role
- arn:aws:iam::123456789012:role/pod-reader-role
command: aws
env: null

--

--

Jeremy Cowan
Jeremy Cowan

Written by Jeremy Cowan

Jeremy Cowan is a Principal Container Specialist at AWS

No responses yet