Create a ServiceAccount, Token and RoleBinding for a (Cluster)-Role (e.g cluster-admin
)¶
Tip
This guide will walk you through setting up kind
and Vault
and its Kubernetes Secret Engine to create a Service Account, Token and RoleBinding for the predefined cluster-admin
ClusterRole
Warning
The cluster-admin
role can do anything in every namespace.
Use with caution
Prerequisites¶
You will need the following tools to be installed:
Setup kind
¶
cat <<EOF >>kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
apiServerAddress: "127.0.0.1"
apiServerPort: 6443
EOF
kind create cluster --config=kind-config.yaml
you should now be able to run kubectl
commands:
kubectl get ns
NAME STATUS AGE
default Active 64m
kube-node-lease Active 64m
kube-public Active 64m
kube-system Active 64m
local-path-storage Active 63m
Configure Vault
access¶
The following manifest, creates a ServiceAccount vault-auth
and assigns it the role cluster-admin-creator
, which allows to create Service Account, Tokens assigning them the a (Cluster)-Role.
Tip
This Service Account is going to be used by Vault
Note
**Kubernetes prevents users (including service accounts) from granting RBAC permissions they do not already have themselves.
Thats why we have to assign bind
and escalate
as verbs
for clusterrolebindings
.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault-auth
automountServiceAccountToken: true
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: vault-auth-token
annotations:
kubernetes.io/service-account.name: vault-auth
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin-creator
rules:
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["create","update", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts/token"]
verbs: ["create", "update", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["create", "patch", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["bind", "escalate"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-creator-binding
subjects:
- kind: ServiceAccount
name: vault-auth
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin-creator
apiGroup: rbac.authorization.k8s.io
EOF
Configure Vault
¶
Lastly, we will need to start and configure a local Vault Server
:
Authenticate to Vault
and check with vault status
:
export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN="root"
> vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.18.3
Build Date 2024-12-16T14:00:53Z
Storage Type inmem
Cluster Name vault-cluster-4cab3957
Cluster ID 597257da-8e8d-6147-c379-e93e3a6013c7
HA Enabled false
Now, we will configure the Kubernetes Secrets Engine to connect to the local kind
Cluster with the vault-auth
ServiceAccount and create a role kind
that will create the ServiceAcccount, Token and RoleBinding:
Important
Note the kubernetes_role_type
and kubernetes_role_name
#!/usr/bin/env bash
set -ex
K8S_JWT_TOKEN=$(kubectl get secret vault-auth-token -o jsonpath="{.data.token}" | base64 -d)
K8S_CA_CERT=$(kubectl get secret vault-auth-token -o jsonpath="{['data']['ca\.crt']}" | base64 -d)
vault secrets enable kubernetes
vault write -f kubernetes/config \
kubernetes_host="https://127.0.0.1:6443" \
kubernetes_ca_cert="$K8S_CA_CERT" \
service_account_jwt="$K8S_JWT_TOKEN"
vault write kubernetes/roles/kind \
allowed_kubernetes_namespaces="default" \
kubernetes_role_name="cluster-admin" \
kubernetes_role_type="ClusterRole" \
token_default_ttl="10m"
Putting it together¶
Write kind
s kubeconfig
to a file:
and update it, to use kubectl-vault-login
for authentication:
KUBECONFIG=./kubeconfig.yml kubectl config set-credentials vault \
--exec-interactive-mode=Never \
--exec-api-version=client.authentication.k8s.io/v1 \
--exec-command=kubectl \
--exec-arg=vault-login \
--exec-arg=--role=kind
> cat kubeconfig.yml
[...]
users:
- name: vault
user:
exec:
apiVersion: client.authentication.k8s.io/v1
args:
- vault-login
- --role=kind
command: kubectl
env: null
interactiveMode: Never
provideClusterInfo: false
# check SA has been created
> KUBECONFIG=kubeconfig.yml kubectl get sa
NAME SECRETS AGE
v-token-kind-1739829804-zbmswmhaet1qelxccyo97uux 0 25s
# check clusterrrolebinding was created
> KUBECONFIG=kubeconfig.yml kubectl get clusterrolebindings -n default
NAME ROLE AGE
v-token-kind-1739829804-zbmswmhaet1qelxccyo97uux ClusterRole/cluster-admin 59s
Teardown¶
Tear everything down by running: