Every pod in a Kubernetes cluster runs as a service account, and in most clusters that identity is either the namespace default, a token the workload never needed, or a bridge to cloud permissions that nobody reviewed. This template is a per-workload sign-off for the identity a workload carries: its Kubernetes service account, the tokens projected into it, the RBAC it holds and the federation that turns it into Amazon Web Services, Google Cloud or Microsoft Azure permissions. Cluster-wide hardening is already covered in the Kubernetes Security Checklist; this checklist goes one level down, to the individual workload and its cloud binding. It is written for platform engineers, application teams that own deployments, and reviewers who approve workloads before production. Platforms are listed alphabetically.
This is an independent guide from NHI Mgmt Group, based on the Kubernetes project's public documentation and the cloud providers' workload identity documentation as of November 2026. It is not sponsored or reviewed by the Kubernetes project or any cloud provider. Product features change, so confirm settings against each provider's current documentation.
How to use this template
- Complete sections 4 to 6 for every workload that runs in [Production clusters], and section 7 for each cloud the workload reaches. Store the result with the workload's deployment repository so it changes with the code.
- "Must" items block production. "Should" items need an exception under section 9.
- Run the "Verify" step against the running pod, not the manifest. Admission controllers, mutating webhooks and Helm values can change what actually runs.
- Replace values in square brackets with your own. Values marked "ours" are NHI Mgmt Group recommendations, not upstream requirements.
- For background, read the Kubernetes Service Account Token Guide, the Kubernetes NHI Security Guide and the Workload Identity Federation Guide.
1. Purpose
This checklist sets the minimum identity configuration for any workload running in [Organisation]'s Kubernetes clusters, and the evidence that proves it. It treats each service account as a non-human identity with an owner, a defined purpose, the least privilege it needs and no static credentials, consistent with NIST CSF 2.0 PR.AA-01 (identities and credentials for authorised users, services and hardware are managed) and NIST SP 800-53 IA-9 (service identification and authentication).
2. Scope
- Deployments, StatefulSets, DaemonSets, Jobs and CronJobs in [Production clusters] and in any non-production cluster that holds production credentials or data.
- Operators and controllers installed from third parties, which often ship cluster-wide service accounts. See the Kubernetes Operator Security guide.
- Federation from a cluster to Amazon EKS Pod Identity or IAM roles for service accounts (IRSA), Microsoft Entra Workload ID on AKS, and Workload Identity Federation for GKE, plus any self-managed cluster federated to a cloud through its OIDC issuer.
- Out of scope: human access to clusters, CI/CD federation (see the GitHub Actions OIDC Federation Hardening Guide) and mesh identities (see the Service Mesh Identity Checklist).
3. Roles and definitions
| Term or role | Meaning here |
|---|---|
| Workload owner | The team that owns the deployment and is accountable for its service account and cloud permissions. |
| [Platform team] | Owns cluster configuration, admission policy, the OIDC issuer and the cloud-side federation plumbing. |
| Projected token | A short-lived token obtained through the TokenRequest API and mounted by the kubelet, which rotates it before expiry. Bound to the pod: the API server checks the pod still exists. |
| Legacy token Secret | A Secret of type kubernetes.io/service-account-token. Created automatically before Kubernetes v1.24; does not expire or rotate. |
| Federated binding | The cloud-side configuration that trusts a cluster's service account tokens: an EKS Pod Identity association or IRSA role trust policy, an Entra federated identity credential, or a GKE IAM binding to a principal:// identifier. |
4. Service account design
| # | Requirement | Level | Verify |
|---|---|---|---|
| 4.1 | The workload runs as a dedicated service account, not the namespace default. One service account per workload; it is not shared between unrelated deployments. | Must | kubectl get pod -o jsonpath='{.spec.serviceAccountName}' on the running pod. |
| 4.2 | The service account carries owner and purpose labels or annotations, for example [org]/owner and [org]/purpose, and is in the [NHI inventory]. | Must | Labels present; inventory record linked. |
| 4.3 | The default service account in the namespace has automountServiceAccountToken: false and no RoleBindings. | Must | Inspect the ServiceAccount object; query bindings whose subject is default. |
| 4.4 | Workloads that do not call the Kubernetes API set automountServiceAccountToken: false in the pod spec (the pod setting takes precedence over the service account). | Must | Running pod shows no /var/run/secrets/kubernetes.io/serviceaccount mount. |
| 4.5 | Service accounts for deleted workloads are removed within [30 days] (ours), together with their bindings and federated cloud bindings. | Should | Report of service accounts with no running pods for [30 days]. |
5. Tokens
| # | Requirement | Level | Verify |
|---|---|---|---|
| 5.1 | No legacy token Secrets exist for this service account. Any needed for an external system are replaced with TokenRequest tokens or federation. | Must | kubectl get secrets --field-selector type=kubernetes.io/service-account-token in the namespace returns nothing for this account. |
| 5.2 | Tokens for anything other than the Kubernetes API are projected with an explicit audience naming that consumer and a short expirationSeconds (ours: 3600 or less, unless the consumer documents otherwise). | Must | Pod spec projected volume shows audience and expiry; decoded token aud matches. |
| 5.3 | The application re-reads the token file on each use rather than caching it at start-up, because the kubelet rotates it in place. | Must | Long-running pod still authenticates after the token's first expiry. |
| 5.4 | Services inside the cluster that accept service account tokens validate them with the TokenReview API, or check audience and expiry. The Kubernetes documentation notes that TokenReview fails as soon as the bound pod is deleted, while OIDC discovery validation trusts the token until it expires. | Should | Code or configuration reviewed. |
| 5.5 | No workload creates long-lived tokens for itself or others, and no RBAC grants create on serviceaccounts/token outside named platform roles. | Must | RBAC query for the serviceaccounts/token subresource. |
For rotation and detection of old token use, follow How to rotate a Kubernetes service account token and detect old token use.
6. RBAC for the workload
| # | Requirement | Level | Verify |
|---|---|---|---|
| 6.1 | Permissions are granted with a namespaced Role and RoleBinding. A ClusterRoleBinding needs a written justification (operators and controllers only). | Must | kubectl auth can-i --list --as=system:serviceaccount:[ns]:[sa] output attached. |
| 6.2 | No wildcard verbs or resources; no escalate, bind or impersonate; no get, list or watch on Secrets unless the workload's purpose requires it, and then scoped by resourceNames. | Must | Same output reviewed against the list. |
| 6.3 | No create on pods or workload controllers unless the workload is a controller, because creating a pod with any service account in the namespace grants that account's rights. | Must | Same output reviewed. |
| 6.4 | RBAC for this account is defined in Git with the workload, so changes are reviewed. | Should | Repository path recorded. |
The Kubernetes RBAC Guide explains which permissions amount to privilege escalation.
7. Cloud federation
Complete the rows for each cloud the workload calls. The common rule: one cloud identity per workload, bound to one namespace and service account in one named cluster, with no static cloud keys in the pod. Detailed trust condition review is in the Workload Identity Federation Trust Review Checklist.
| # | Platform | Requirement | Verify |
|---|---|---|---|
| 7.1 | All | No cloud access keys, service account key files or client secrets are mounted as Secrets or environment variables for this workload (Must). | Search the namespace's Secrets and the pod environment for key patterns; secret scanning result attached. |
| 7.2 | Amazon EKS | The workload uses an EKS Pod Identity association (service account in a namespace mapped to one IAM role, trust principal pods.eks.amazonaws.com) or IRSA with a trust policy whose subject condition names this namespace and service account (Must). Pod access to the instance metadata service is restricted so pods cannot obtain the node role (Must). | Association or trust policy exported; from the pod, the node role credentials are not reachable. |
| 7.3 | Azure AKS | The cluster OIDC issuer and workload identity are enabled; the service account carries azure.workload.identity/client-id; the pod template has the label azure.workload.identity/use: "true"; the federated identity credential names this cluster's issuer, subject system:serviceaccount:[ns]:[sa] and audience api://AzureADTokenExchange (Must). Pod-managed identity is migrated to Workload ID (Should). | Federated credential exported; pod shows AZURE_FEDERATED_TOKEN_FILE. |
| 7.4 | Google GKE | Workload Identity Federation for GKE is enabled on the cluster and the node pool runs the GKE metadata server; IAM grants go to the principal:// identifier for this namespace and service account, not a principalSet:// covering a whole namespace or cluster, unless justified (Must). Because the pool PROJECT_ID.svc.id.goog is shared by every cluster in the project, the same namespace and service account name in another cluster is the same identity: either keep untrusted clusters in separate projects or add an IAM condition limiting access to the named cluster (Must). | IAM policy exported; list of clusters in the project attached. |
| 7.5 | Self-managed | The cluster's --service-account-issuer URL is stable and unique to the cluster, its discovery document and JWKS are published where the cloud can reach them, and signing key rotation is documented (Must). | Discovery URL and key rotation runbook recorded. |
| 7.6 | All | The cloud role or identity has only the permissions the workload needs, scoped to named resources, and is reviewed every [6 months] (ours) (Must). | Policy attached; last review date. |
Availability: EKS Pod Identity, AKS Workload ID and GKE workload identity each have documented node type, region and quota conditions (for example, AWS documents Pod Identity for Linux EC2 worker nodes). Confirm the current conditions in each provider's documentation for your cluster type. To move existing GKE workloads off keys, see How to move GKE workloads from keys to Workload Identity Federation.
8. Threat and framework mapping
| Threat | Checks | Framework reference |
|---|---|---|
| Token read from a compromised container and used against the API (MITRE ATT&CK T1528 Steal Application Access Token) | 4.4, 5.1, 5.2, 6.2 | NIST SP 800-53 IA-5, AC-6 |
| Node or cloud credentials taken from the metadata service (T1552.005 Cloud Instance Metadata API) | 7.1, 7.2, 7.4 | NIST SP 800-53 IA-9, AC-6 |
| Secrets read through the API (T1552.007 Container API) | 6.2, 7.1 | NIST SP 800-53 AC-6; NIST CSF 2.0 PR.AA-05 |
| Cloud access through valid federated identity (T1078.004 Cloud Accounts) | 7.2 to 7.6 | NIST SP 800-53 AC-2; NIST CSF 2.0 PR.AA-01 |
| Privilege escalation by creating pods with a stronger service account | 6.1, 6.3 | NIST SP 800-53 AC-6 |
9. Exceptions, monitoring and review
- Exceptions: recorded in [Risk register] with reason, compensating control, owner and a review date within [6 months]. A static cloud key (7.1) needs [CISO] approval, a rotation interval and a migration date.
- Monitoring: Kubernetes audit logs record TokenRequest calls, RoleBinding changes and Secret reads; cloud logs (AWS CloudTrail, Azure Monitor sign-in logs for workload identities, Google Cloud Audit Logs) record the federated exchanges. Alert on token use from outside the cluster's egress addresses and on new federated bindings. See the Kubernetes Audit Log Detection Guide.
- Metrics: percentage of pods on the
defaultservice account; count of legacy token Secrets; percentage of pods with a mounted token that call the API; count of workloads holding static cloud keys; federated bindings without an owner. - Review: re-run this checklist when the workload's permissions or cloud targets change, after each cluster minor upgrade and every [12 months].
Implementation guidance
- Inventory first: export every service account, its bindings, legacy token Secrets and the cloud bindings that point at the cluster. The gap between the two lists (cloud bindings for service accounts that no longer exist) is often the most urgent finding.
- Turn off automounting on default accounts namespace by namespace, after checking audit logs for API calls from pods using
default. Rollback is reverting the ServiceAccount object. - Enforce with admission policy in audit mode, then deny: pods using
default, pods with mounted tokens and no API need, and Secrets containing cloud keys. See the Kubernetes Admission Control Guide. - Move cloud access to federation workload by workload, running the static key and the federated identity side by side for one release, then revoking the key and watching cloud logs for its use.
- Bake the checklist into the namespace template so new teams start compliant; the Kubernetes Namespace Onboarding Checklist covers the namespace side.
Small teams on one managed cluster can meet most items with provider defaults plus admission policy. Large estates with many clusters per cloud project or account should treat identity sameness (7.4) and shared trust policies as a design decision, not a configuration detail.
Standards and references
- Kubernetes: Service Accounts
- AWS: Learn how EKS Pod Identity grants pods access to AWS services
- Microsoft Learn: Use Microsoft Entra Workload ID with Azure Kubernetes Service
- Google Cloud: About Workload Identity Federation for GKE
- MITRE ATT&CK: Cloud Instance Metadata API
- NIST: SP 800-53 Rev. 5
- NIST: Cybersecurity Framework 2.0
This template is provided for guidance and must be adapted to your organisation. Related NHI Mgmt Group resources: Kubernetes NHI Security Guide · Kubernetes Service Account Token Guide · Cloud Workload Identity Guide · Kubernetes Security Checklist