Create a user and give it access

What we are going to do

There are several ways to create a user in Kubernetes, including a client certificate, Serviceaccount, and OpenID Connect.

We’ll focus on how to create a user in Kubernetes using client certificates and ServiceAccount.

Prerequisites

Before you begin you need to have a Kubernetes cluster and the kubectl command-line tool and also you need to know the concept of ClusterRole and ClusterRoleBinding in Kubernetes.

If you do not already have a cluster setup one in killercoda.

We have also tested all the below commands on Kubernetes version v1.29.0.

Client certificate

We will create a user with admin permissions and most importantly we will be able to revoke access to it.

The default admin kubeconfig file has a system:masters group that allows for unrestricted access to the Kubernetes API server without the need for any roles or rolebindings. so if you create a user with this permission It’s hard to revoke the permissions (actually you need to create a new certificate authority for Kubernetes and sign again most of the Kubernetes components and because most of the Kubernetes installers like Kubeadm don’t support CA rotation we can consider it a hard work)

To grant temporary admin access to someone, we can assign them to a designated ClusterRole, such as cluster-admin, and assign its permission by ClusterRoleBinding(Or we can use our costume ClusterRole).

Steps

  1. Create a private key for the new user
  2. Now, we will create a certificate signing request (CSR) with the private key
  3. Now you need to sign the certificate with the Private CA of your Kubernetes certificate (The CertificateSigningRequest does that for us)
  4. Create a ClusterRoleBinding to assign the cluster-admin ClusterRole permissions to the user
  5. Generate a new kubeconfig file for the user
openssl genrsa -out test-user.key 2048 # The private key 
openssl req -new -key test-user.key -out test-user.csr -subj "/CN=test-user/O=test-admin"

# Sign the CSR with the CA (Certificate authority of Kubernetes) you can also do (`openssl x509 -req -in myuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out test-user.crt -days 365`
 if you are logged in the one of master nodes)

cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: test-user
spec:
  request: $(cat test-user.csr | base64 | tr -d "\n")
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
EOF

kubectl certificate approve test-user
kubectl get csr test-user -o "jsonpath={.status.certificate}" | base64 -d  > test-user.crt

# Create ClusterRole
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: example-cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: test-admin
EOF

# Create Kubeconfig file
kubectl --kubeconfig ~/.kube/config-test-user config set-cluster preprod --insecure-skip-tls-verify=true --server=https://127.0.0.1:6443
kubectl --kubeconfig ~/.kube/config-test-user config set-credentials test-user --client-certificate=test-user.crt --client-key=test-user.key --embed-certs=true
kubectl --kubeconfig ~/.kube/config-test-user config set-context default --cluster=preprod --user=test-user
kubectl --kubeconfig ~/.kube/config-test-user config use-context default 
# Check the Permissions
kubectl get nodes --kubeconfig ~/.kube/config-test-user

Remove the permission of the user

By changing cluster-admin ClusterRole we can change the permission of the user, or by deleting the example-cluster-admin ClusterRoleBinding we can disable all the permissions we have given to the user.

Service Account

Now let’s create a user with a ServiceAccount

  • Create ServiceAccount
kubectl create sa test-user
  • In Kubernetes 1.24, ServiceAccount token secrets are no longer automatically generated. so we need to create a secret manually
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: test-user
  name: test-user
type: kubernetes.io/service-account-token
EOF
  • Then give it permission, We will give it the cluster-admin ClusterRole that has been created automatically by Kubernetes
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: example-cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: test-user
  namespace: default
EOF
  • Now generate a kubeconfig file for the user

TOKEN=$(kubectl get secret test-user -o jsonpath='{.data.token}' | base64 -d )

kubectl --kubeconfig ~/.kube/config-test-user config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://127.0.0.1:6443 # If you want not to use insecure-skip-tls-verify you need to add CA certificate of kubernetes in the config
kubectl --kubeconfig ~/.kube/config-test-user config set-credentials test-user --client-certificate=test-user.crt --client-key=test-user.key --embed-certs=true
kubectl --kubeconfig ~/.kube/config-test-user config set-context default --cluster=kubernetes --user=test-user --username=test-user
kubectl --kubeconfig ~/.kube/config-test-user config use-context default 
kubectl --kubeconfig ~/.kube/config-test-user config set-credentials test-user --token $TOKEN
# Check the Permissions
kubectl get nodes --kubeconfig ~/.kube/config-test-user

Leave a Reply

Your email address will not be published. Required fields are marked *