Review ServiceAccount sharing

Separate ServiceAccounts for workloads with different purposes and permission needs.

Description

Workloads using the same ServiceAccount in the same namespace share an API identity and the permissions granted to that account. Modern Pod-bound tokens can be issued separately for each Pod, so sharing an account does not always mean using identical token values.

Separate accounts when workloads have different purposes and permission requirements. Replicas of the same application may intentionally share the same permissions.

Potential impact

  • Permissions needed by one workload can also become available to other workloads using the account.
  • Calls from a shared identity can make it harder to distinguish workloads in audit records.

Remediation

  • Use separate ServiceAccounts for workloads with different purposes or permission needs. Review each account’s RoleBindings and actually permitted operations.
  • Specify the account each pod uses and disable automatic mounting when an API token is unnecessary. Plan permission changes and token-incident response with all pods using the account in mind.

Examples

Each excerpt shows only one pod. The comparison assumes that other workloads also use the first account; the code alone does not establish sharing. Prepare the account first and use a maintained image for deployment.

Before

hcl
resource "kubernetes_pod" "pod" {
  metadata {
    name = "with-pod-affinity"
  }

  spec {
    container {
      name  = "with-pod-affinity"
      image = "k8s.gcr.io/pause:2.0"
    }

    service_account_name = "terraform-example"
  }
}

resource "kubernetes_service_account" "shared" {
  metadata {
    name = "terraform-example"
  }
}

After

hcl
resource "kubernetes_pod" "pod" {
  metadata {
    name = "with-pod-affinity-2"
  }

  spec {
    container {
      name  = "with-pod-affinity"
      image = "k8s.gcr.io/pause:2.0"
    }

    service_account_name = "service-name"
  }
}

resource "kubernetes_service_account" "dedicated" {
  metadata {
    name = "service-name"
  }
}

Explanation:

  • Before: The pod uses terraform-example. Check whether other workloads with different purposes also use that account.
  • After: The pod uses a separate service-name account. Its actual permissions must also be limited.

References