> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Client Certificate Authentication Should Not Be Used For Users

### More Info:

Kubernetes provides the option to use client certificates for user authentication. However as there is no way to revoke these certificates when a user leaves an organization or loses their credential, they are not suitable for this purpose. It is not possible to fully disable client certificate use within a cluster as it is used for component to component authentication.

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify all client-certificate-based user configs on admin machines (evidence gathering)**
           * On any machine with kubectl access, search typical kubeconfig locations for client-certificate auth (non-service-account):
             ```bash theme={null}
             grep -RInE "client-certificate:|client-certificate-data:" \
               $HOME/.kube /etc/kubernetes/admin.conf /etc/kubernetes/controller-manager.conf \
               /etc/kubernetes/scheduler.conf 2>/dev/null
             ```
           * For each kubeconfig found, list users and auth methods:
             ```bash theme={null}
             KUBECONFIG=$HOME/.kube/config kubectl config view --minify=false --raw
             ```
           * Decision: treat any context where `user` has `client-certificate`/`client-certificate-data` and is used by a human admin/script (not a core control-plane component) as non-compliant.

        2. **Confirm which client-cert identities have cluster privileges**
           * On any machine with kubectl access, list ClusterRoleBindings/RoleBindings that reference `User` subjects (these may be backed by client certs):
             ```bash theme={null}
             kubectl get clusterrolebindings -o yaml | grep -B5 -A5 "kind: User"
             kubectl get rolebindings --all-namespaces -o yaml | grep -B5 -A5 "kind: User"
             ```
           * For each `User` subject, note whether that identity corresponds to a client certificate user from kubeconfig.
           * Decision: if such users are humans or automation that could instead use OIDC or another revocable mechanism, mark them for migration.

        3. **Design and enable an alternative auth mechanism (e.g., OIDC) on every control plane node**
           * On every control plane node, review the current API server flags to see if OIDC (or another centralized identity provider) is already configured:
             ```bash theme={null}
             ps -eo args | grep kube-apiserver | grep -v grep
             ```
           * If OIDC is not enabled, follow your organization’s identity design to add the appropriate `--oidc-*` flags (issuer-url, client-id, etc.) to the kube-apiserver manifest, usually at:\
             `/etc/kubernetes/manifests/kube-apiserver.yaml`
             * Editing this static pod manifest will restart the API server on that node.
           * Decision: only proceed once a revocable and centrally managed authentication method is configured and tested.

        4. **Migrate human and automation users from client certs to OIDC (or chosen mechanism)**
           * On any machine with kubectl access, for each non-compliant user:
             1. Create or identify the corresponding OIDC identity (subject/claim) in your IdP.
             2. Create/update Kubernetes `RoleBinding`/`ClusterRoleBinding` to grant the same roles to the new `User`/`Group` as identified by OIDC claims. Example (adapt to your IdP and roles):
                ```bash theme={null}
                kubectl apply -f - <<'EOF'
                apiVersion: rbac.authorization.k8s.io/v1
                kind: ClusterRoleBinding
                metadata:
                  name: oidc-admins
                subjects:
                - kind: Group
                  name: your-oidc-admin-group
                roleRef:
                  kind: ClusterRole
                  name: cluster-admin
                  apiGroup: rbac.authorization.k8s.io
                EOF
                ```
           * Update kubeconfig used by each human/automation to use OIDC auth (e.g., via an exec plugin or cloud CLI) instead of client certificate fields.

        5. **Remove or de-privilege client-certificate users once migration is confirmed**
           * On any machine with kubectl access, after verifying affected users can authenticate and operate via OIDC:
             * Remove or adjust RBAC bindings that reference the old client-cert `User` identities:
               ```bash theme={null}
               # Example: delete a specific ClusterRoleBinding
               kubectl delete clusterrolebinding <old-client-cert-crb-name>
               ```
             * Optionally, revoke or delete the issuing CA or intermediate used solely for those user client certs in your PKI system (outside the cluster), ensuring it does not impact component-to-component certs.
           * On admin machines, clean up outdated kubeconfigs that still contain `client-certificate` for humans or automation:
             ```bash theme={null}
             sed -i.bak '/client-certificate-data:/d;/client-key-data:/d;/client-certificate:/d;/client-key:/d' $HOME/.kube/config
             ```

        6. **Verify that client certificate authentication is no longer used for users (only components)**
           * On any machine with kubectl access, re-check kubeconfigs:
             ```bash theme={null}
             grep -RInE "client-certificate:|client-certificate-data:" \
               $HOME/.kube /etc/kubernetes/admin.conf /etc/kubernetes/controller-manager.conf \
               /etc/kubernetes/scheduler.conf 2>/dev/null
             ```
             Ensure only control-plane/component configs (e.g., `kube-apiserver`, `kube-controller-manager`, `kube-scheduler`, `kubelet`) use client certs.
           * Confirm RBAC no longer grants roles to user identities that are only accessible via client certs by re-running:
             ```bash theme={null}
             kubectl get clusterrolebindings -o yaml | grep -B5 -A5 "kind: User"
             kubectl get rolebindings --all-namespaces -o yaml | grep -B5 -A5 "kind: User"
             ```
             and ensuring any remaining `User` subjects correspond only to component identities or identities authenticated via your new mechanism.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify client certificate authentication for users because this is controlled by host-level configuration and API server flags on every control plane node. Make the necessary changes directly on those nodes as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Purpose:
        #   Enumerate where client-certificate authentication is used for *users*
        #   (as opposed to internal components), so it can be reviewed and phased
        #   out in favor of OIDC or other revocable mechanisms.
        #
        # Requirements:
        #   - Run on any machine with kubectl and (optionally) openssl/jq
        #   - KUBECONFIG configured with access to the cluster

        set -euo pipefail

        echo "=== 1) kubectl user identities (from current kubeconfig) ==="
        # Machine: any machine with kubectl access
        kubectl config view --flatten --output='jsonpath={.users[*].name}' | tr ' ' '\n' | sort -u | sed '/^$/d' || true

        echo
        echo "For each user above, inspect its auth mechanism:"
        echo

        # Show full users section so you can see client-certificate-data / client-key-data use
        kubectl config view --flatten -o json | jq '.users' 2>/dev/null || kubectl config view --flatten

        cat <<'EOF'

        Interpretation:
        - Any user entry that has fields like:
            "client-certificate": "path/to/cert"
            "client-key": "path/to/key"
          or:
            "client-certificate-data": "BASE64..."
            "client-key-data": "BASE64..."
          is using client certificate authentication.
        - These are *suspect* for this control if they represent human users rather than components
          (e.g. "alice", "devops-admin", "ci-bot" vs "kubernetes-admin", "system:admin", or node identities).

        Action:
        - Flag human/long‑lived users that rely on client certs and plan migration to OIDC or another
          revocable method.

        EOF

        echo "=== 2) Detect client‑certificate auth in kubeconfig used by common automation accounts ==="
        echo "Checking for client-certificate usage in typical locations (~/.kube/config, KUBECONFIG)..."
        echo

        for cfg in "$HOME/.kube/config" ${KUBECONFIG:-}; do
          [ -f "$cfg" ] || continue
          echo "---- $cfg ----"
          if grep -E 'client-certificate|client-certificate-data' "$cfg" >/dev/null 2>&1; then
            echo "POTENTIAL PROBLEM: client-certificate auth is in use in this kubeconfig."
            grep -nE 'name:|user:|client-certificate|client-certificate-data' "$cfg" | sed 's/^/  /'
          else
            echo "OK: no client-certificate fields found in this kubeconfig (may be using tokens/OIDC)."
          fi
          echo
        done

        cat <<'EOF'

        Interpretation:
        - Lines under a user that reference client-certificate / client-certificate-data indicate use
          of client cert auth. If those users are humans or long-lived service accounts, they are
          non-compliant with this control.
        - Kubeconfigs that use:
            - exec: plugins (e.g. aws-iam-authenticator, gcloud, az) or
            - id-token / access-token / auth-provider: oidc
          are generally OK for this control.

        EOF

        echo "=== 3) Identify client‑certificate usage from apiserver audit logs (if available) ==="
        echo "NOTE: This is optional and depends on audit logging configuration and log access."
        echo "      Run the following on every control plane node that has API server audit logs:"
        cat <<'EOF'

        # On every control plane node (adjust paths to your environment):

        AUDIT_DIR="/var/log/kubernetes/audit"   # or /var/log/kube-apiserver, /var/log/apiserver, etc.
        LOG_FILE_PATTERN="*.log"

        # Example grep to show client certificate subjects seen by the apiserver:
        sudo find "$AUDIT_DIR" -name "$LOG_FILE_PATTERN" -type f -print0 2>/dev/null | \
          xargs -0 sudo grep -Eo '"user":{"username":"[^"]+","groups":\[[^]]*\],"extra":\{[^}]*"authentication.kubernetes.io/x509name":"[^"]+"' | \
          sed 's/.*"username":"\([^"]\+\)".*"authentication.kubernetes.io\/x509name":"\([^"]\+\)".*/USERNAME=\1  X509_SUBJECT=\2/' | \
          sort -u

        EOF

        cat <<'EOF'

        Interpretation:
        - Any USERNAME/X509_SUBJECT pairs you see there are identities that authenticated
          with an X.509 client certificate.
        - If those usernames correspond to human or long‑lived users (as opposed to
          system: nodes, controllers, or internal components), they are in scope for this finding.

        EOF

        echo "=== 4) Summary: what indicates a problem? ==="
        cat <<'EOF'
        You have a *problem* for this control when:
        - A human user or long‑lived non‑system identity (e.g. "alice", "team-admin",
          "jenkins-prod") in kubeconfig or in audit logs is authenticated via a client
          certificate (client-certificate / client-certificate-data).
        You are *aligned* with the control when:
        - Humans and long‑lived identities authenticate using OIDC or another revocable
          mechanism (tokens tied to IdP or short‑lived cloud IAM credentials), and
        - Client certificate authentication is only used for internal Kubernetes
          components where it cannot be disabled.

        This script does not and cannot automatically fix the issue; it only surfaces
        where client certificate auth is being used so you can plan migration to OIDC
        or another revocable mechanism per the benchmark guidance.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
