5. Kubernetes Users, Accounts

5.1. User and Service Accounts

In kubernetes there is a distinction between two categories of accounts that can access the API and operate on the cluster: user accounts and service accounts (see [users-01] and [users-02]).

User accounts:

  • Intended to be used by humans

  • Assumed to be managed by an outside service (i.e., can’t be created or deleted by the kubernetes API)

Service accounts:

  • Intended to be used by processes

  • Managed by the kubernetes API

5.2. Initial admin user account details

When a cluster is initially provisioned you get admin credentials that let you do anything on the cluster (sort of a “root password” for the cluster).

An example of the kubeconfig for a cluster provisoned kubeadm init:

 kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://kubernetes.docker.internal:6443
  name: docker-desktop
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.11.112:6443
  name: kubernetes-x131e
...
...
contexts:
- context:
    cluster: docker-desktop
    user: docker-desktop
  name: docker-desktop
- context:
    cluster: kubernetes-x131e
    user: kubernetes-admin-x131e
  name: kubernetes-admin-x131e@kubernetes-x131e
...
...
current-context: kubernetes-admin-x131e@kubernetes-x131e
kind: Config
preferences: {}
users:
- name: docker-desktop
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: kubernetes-admin-x131e
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
...
...

The client certificate contains information that identifies the user and relates it to the cluster roles and role bindings. We can decode the client cert information as follows:

  • Get the user in the current context. For a simple kubeconfig like the one above it can be done by simple inspection (user: kubernetes-admin-x131e). This can also be done programmatically, using for example:

     kubectl config view -o json \
      | jq ".contexts[] | select(.name==\"$(kubectl config current-context)\")" \
      | jq -r ".context.user"
    
  • Decode the client-certificate-data for the corresponding user and extract the Subject information

      k8s_current_user=$(kubectl config view -o json \
      | jq ".contexts[] | select(.name==\"$(kubectl config current-context)\")" \
      | jq -r ".context.user")
    
    ~  kubectl config view --raw -o json \
      | jq ".users[] | select(.name==\"$k8s_current_user\")" \
      | jq -r ".user.\"client-certificate-data\"" \
      | base64 -d | openssl x509 -text | grep "Subject:"
    
        Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin
    

    O: organization (group in kubernetes) / CN: common name (user in kubernetes)

  • With the group information from the certificate, we can obtain the corresponding clusterrolebinding (using either kubectl describe or kubectl get)

     kubectl describe clusterrolebindings.rbac.authorization.k8s.io kubeadm:cluster-admins
    
    Name:         kubeadm:cluster-admins
    Labels:       <none>
    Annotations:  <none>
    Role:
      Kind:  ClusterRole
      Name:  cluster-admin
    Subjects:
      Kind   Name                    Namespace
      ----   ----                    ---------
      Group  kubeadm:cluster-admins
    
    → k8s_current_group="kubeadm:cluster-admins" kubectl get clusterrolebindings.rbac.authorization.k8s.io -o json \
      | jq ".items[] | select(.subjects[].name==\"$k8s_current_group\")"
    {
      "apiVersion": "rbac.authorization.k8s.io/v1",
      "kind": "ClusterRoleBinding",
      "metadata": {
        "creationTimestamp": "2025-04-05T21:09:42Z",
        "name": "kubeadm:cluster-admins",
        "resourceVersion": "251",
        "uid": "6fc4fd6e-638d-44c7-b375-e3c7c0759dd4"
      },
      "roleRef": {
        "apiGroup": "rbac.authorization.k8s.io",
        "kind": "ClusterRole",
        "name": "cluster-admin"
      },
      "subjects": [
        {
          "apiGroup": "rbac.authorization.k8s.io",
          "kind": "Group",
          "name": "kubeadm:cluster-admins"
        }
      ]
    }
    
  • With the ClusterRole name in the clusterrolebinding (“cluster-admin”) we can get the information of the corresponding clusterrole (using either kubectl describe or kubectl get)

     kubectl describe clusterroles.rbac.authorization.k8s.io cluster-admin
    Name:         cluster-admin
    Labels:       kubernetes.io/bootstrapping=rbac-defaults
    Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      *.*        []                 []              [*]
                 [*]                []              [*] kubectl get clusterroles.rbac.authorization.k8s.io -o json \
      | jq ".items[] | select(.metadata.name==\"cluster-admin\")"
    {
      "apiVersion": "rbac.authorization.k8s.io/v1",
      "kind": "ClusterRole",
      "metadata": {
        "annotations": {
          "rbac.authorization.kubernetes.io/autoupdate": "true"
        },
        "creationTimestamp": "2025-04-05T21:09:39Z",
        "labels": {
          "kubernetes.io/bootstrapping": "rbac-defaults"
        },
        "name": "cluster-admin",
        "resourceVersion": "70",
        "uid": "3a75c321-4307-4c27-90ae-24e005e75214"
      },
      "rules": [
        {
          "apiGroups": [
            "*"
          ],
          "resources": [
            "*"
          ],
          "verbs": [
            "*"
          ]
        },
        {
          "nonResourceURLs": [
            "*"
          ],
          "verbs": [
            "*"
          ]
        }
      ]
    }
    

5.3. References