Skip to main content

More Info:

Kubernetes workloads should not use cluster node service accounts to authenticate to Amazon EKS APIs. Each Kubernetes workload that needs to authenticate to other AWS services using AWS IAM should be provisioned with a dedicated service account.

Risk Level

High

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS EKS
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Manual Steps

  1. Identify pods using node IAM role credentials
    • On any machine with kubectl access, list all namespaces and pods that appear to use the EC2 instance role (for example via environment variables or mounted credential files):
    • In the AWS console, review the IAM policies attached to your EKS worker node instance profile; if they include broad permissions for application services (S3, DynamoDB, SQS, etc.), those workloads are likely relying on node roles.
  2. Confirm IRSA (IAM Roles for Service Accounts) is enabled for the cluster
    • On any machine with AWS CLI configured, check for the OIDC provider associated with your EKS cluster (replace the cluster name and region):
    • If this returns None or an empty value, create an IAM OIDC provider for the cluster using the AWS console or:
  3. Select one workload that currently uses node credentials and analyze its access needs
    • On any machine with kubectl access, inspect a representative pod:
    • Determine what AWS services the application actually needs (for example from code, documentation, or environment variables like S3_BUCKET, QUEUE_URL).
    • Document the minimal IAM permissions required (actions and resources) for this workload.
  4. Create a dedicated IAM role and Kubernetes service account for that workload (IRSA)
    • On any machine with AWS CLI configured, create an IAM role that trusts the EKS OIDC provider and your chosen service account (substitute the actual OIDC URL, namespace, and service account name):
    • On any machine with kubectl access, create/annotate the Kubernetes service account to use this role:
      Replace ACCOUNT_ID with your actual account ID.
  5. Migrate the workload to use the dedicated service account instead of node credentials
    • On any machine with kubectl access, patch or update the workload spec to reference the new service account and remove explicit long-term credentials or metadata-URL usage from the pod spec:
    • Ensure application code is using standard AWS SDK credential resolution (no hard-coded keys, no direct calls to 169.254.169.254) so it automatically uses the IRSA-provided credentials.
  6. Verify correct use of dedicated service accounts and plan node-role permissions reduction
    • On any machine with kubectl access, confirm the running pod uses the intended service account:
    • Inside the pod, validate AWS identity (replace pod name and container as appropriate):
      The returned ARN should be the IRSA role (for example arn:aws:iam::ACCOUNT_ID:role/my-workload-role), not the node instance profile.
    • Once a sufficient number of workloads have migrated to IRSA, review and tighten the IAM policy attached to the EKS node instance role in the AWS console or via:
      Detach or narrow any application-specific permissions so that pods are no longer relying on the node role for AWS API access.
kubectl can’t change how pods obtain AWS credentials or how IAM roles are bound to service accounts; this is configured in the EKS control plane and AWS IAM (console/CLI/IaC). To address this finding, follow the guidance in the Manual Steps section using AWS tooling rather than kubectl.

Additional Reading: