> ## 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.

# Prefer Using Dedicated Service Accounts

### More Info:

Assign each pod a dedicated service account instead of relying on the default service account, so that permissions can be scoped per workload.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List all workloads and their service accounts**
           * Run on: any machine with `kubectl` access
           * Command (per namespace; start with production namespaces):
             ```bash theme={null}
             kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName' | sort
             ```
           * Identify pods where `SA` is empty or `default`, especially for internet-facing, privileged, or data-sensitive workloads.

        2. **Review namespace-level usage of the default service account**
           * Run on: any machine with `kubectl` access
           * Commands:
             ```bash theme={null}
             kubectl get sa -A
             kubectl get sa default -n <namespace> -o yaml
             kubectl get rolebinding,clusterrolebinding -A | grep default | grep ServiceAccount
             ```
           * Decide per namespace whether the `default` service account is (a) unused and should stay unprivileged, or (b) used by many workloads and should be replaced with per-workload service accounts.

        3. **Design dedicated service accounts and permissions (IaC / control-plane configuration)**
           * In your cloud/IaC configuration (e.g., Helm values, Terraform, CD pipeline manifests, or cloud console workload configuration screens), for each application:
             * Define a dedicated `ServiceAccount` object name (e.g., `orders-api-sa`).
             * Bind that service account only to the minimal `Role`/`ClusterRole` needed.
           * Example manifest snippet to model in IaC (do not apply with `kubectl` if you manage via IaC):
             ```yaml theme={null}
             apiVersion: v1
             kind: ServiceAccount
             metadata:
               name: orders-api-sa
               namespace: prod
             ```

        4. **Update workload definitions to use dedicated service accounts**
           * In your cloud provider console, CLI, or IaC for each deployment/statefulset/cronjob:
             * Set `spec.template.spec.serviceAccountName` to the dedicated service account.
           * Example pod template snippet for IaC/console:
             ```yaml theme={null}
             spec:
               template:
                 spec:
                   serviceAccountName: orders-api-sa
             ```
           * Redeploy workloads via your normal CI/CD or cloud provider deployment mechanism.

        5. **Optionally restrict the default service account**
           * In namespaces where dedicated service accounts are now used for all meaningful workloads:
             * Ensure the `default` service account has no elevated `RoleBinding`/`ClusterRoleBinding`. Remove or adjust bindings in IaC/cloud console where they reference `default`.
           * If your provider supports toggling “automount service account token” at namespace or service account level, disable it for `default` where practical.

        6. **Verify that dedicated service accounts are in use**
           * Run on: any machine with `kubectl` access
           * Commands:
             ```bash theme={null}
             kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName' | sort
             ```
             Confirm that all non-trivial workloads show a specific, non-`default` service account. For a spot check, inspect a pod’s full spec:
             ```bash theme={null}
             kubectl get pod <pod-name> -n <namespace> -o yaml | grep -n 'serviceAccountName'
             ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot remediate this finding because it concerns how workloads are defined and deployed in your cloud provider / IaC configuration, not a one-off API change. Make the changes in your cloud console, CI/CD pipeline, or IaC templates to assign explicit, non-default service accounts to pods, and follow the guidance in the Manual Steps section to review and update those definitions.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report pods that use the default service account in each namespace.
        # Run on: any machine with kubectl access and correct kubeconfig.
        # Requirements: kubectl, jq
        set -euo pipefail

        # Ensure kubectl works
        kubectl auth can-i list pods >/dev/null 2>&1 || {
          echo "ERROR: Current identity cannot list pods cluster-wide." >&2
          exit 1
        }

        echo "=== Pods using default service accounts per namespace ==="
        echo

        # Header
        printf "%-30s %-50s %-30s\n" "NAMESPACE" "POD" "SERVICE_ACCOUNT"
        printf -- "%0.s-" {1..120}; echo

        # Iterate all namespaces
        for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); do
          # List all pods with their namespace, name, serviceAccountName
          kubectl get pods -n "$ns" -o json \
          | jq -r '
              .items[]
              | {
                  ns: .metadata.namespace,
                  pod: .metadata.name,
                  sa: (.spec.serviceAccountName // "default")
                }
              | select(.sa == "default")
              | "\(.ns) \(.pod) \(.sa)"
            ' 2>/dev/null \
          | while read -r ns_name pod_name sa_name; do
              printf "%-30s %-50s %-30s\n" "$ns_name" "$pod_name" "$sa_name"
            done
        done

        echo
        echo "=== Summary: count of pods using the default service account per namespace ==="
        echo

        kubectl get pods --all-namespaces -o json \
        | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                sa: (.spec.serviceAccountName // "default")
              }
            | select(.sa == "default")
            | .ns
          ' \
        | sort \
        | uniq -c \
        | awk '{printf "namespace=%-40s pods_using_default_sa=%s\n", $2, $1}'
        ```

        **How to interpret the output**

        * Any line in the first table shows a pod currently using the `default` service account in its namespace.
        * Namespaces with a non-zero `pods_using_default_sa` count in the summary need review.
        * For each such pod, decide (manually) whether:
          * It is acceptable for it to use the namespace’s `default` service account with its current RBAC, or
          * You should create and assign a dedicated, least-privilege service account via your cloud/IaC configuration.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
