Skip to content

EKS + ArgoCD: IAM Authentication Setup

Two options when ArgoCD and the target EKS cluster run in AWS: IRSA (requires OIDC provider, service account annotation) and Pod Identity (requires EKS Pod Identity Agent add-on, no annotation needed). The cluster Secret format and target cluster role are identical for both — only the management role trust policy and ArgoCD service account setup differ.

Scenario 1: Same Account

ArgoCD management IAM role

Create a role that both argocd-application-controller and argocd-server will assume. Trust policy:

{
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::<ARGOCD_ACCOUNT_ID>:oidc-provider/oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:sub": [
          "system:serviceaccount:argocd:argocd-application-controller",
          "system:serviceaccount:argocd:argocd-server"
        ]
      }
    }
  }]
}

Permissions policy: allow sts:AssumeRole on * (or scoped to specific cluster role ARNs).

Annotate both ArgoCD service accounts with the management role ARN:

eks.amazonaws.com/role-arn: arn:aws:iam::<ARGOCD_ACCOUNT_ID>:role/<ARGOCD_MANAGEMENT_ROLE>

Target cluster IAM role

Create a role in the target cluster's account. Trust policy — allow the management role to assume it:

{
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::<ARGOCD_ACCOUNT_ID>:role/<ARGOCD_MANAGEMENT_ROLE>"
    },
    "Action": "sts:AssumeRole"
  }]
}

Grant cluster access: add the role to aws-auth (ConfigMap mode) or create an access entry with AmazonEKSClusterAdminPolicy (EKS API mode).

Cluster Secret

apiVersion: v1
kind: Secret
metadata:
  labels:
    argocd.argoproj.io/secret-type: cluster
  name: <CLUSTER-NAME>
type: Opaque
stringData:
  name: "arn:aws:eks:<REGION>:<TARGET_ACCOUNT_ID>:cluster/<CLUSTER_NAME>"
  server: "https://<CLUSTER_ID>.gr7.<REGION>.eks.amazonaws.com"
  config: |
    {
      "awsAuthConfig": {
        "clusterName": "<CLUSTER_NAME>",
        "roleARN": "arn:aws:iam::<TARGET_ACCOUNT_ID>:role/<TARGET_CLUSTER_ROLE>"
      },
      "tlsClientConfig": { "insecure": false, "caData": "<BASE64_CA_DATA>" }
    }

Retrieve endpoint and CA data:

aws eks describe-cluster --name <CLUSTER_NAME> --query "cluster.endpoint" --output text
aws eks describe-cluster --name <CLUSTER_NAME> --query "cluster.certificateAuthority.data" --output text

Scenario 2: Cross-Account

Identical to Scenario 1. The management role trust policy and cluster Secret format are unchanged — only the account IDs differ. The roleARN in the cluster Secret config points to a role in a different AWS account.

Alternative: EKS Pod Identity

Pod Identity replaces IRSA on the ArgoCD cluster side. The target cluster role and cluster Secret are unchanged. Requires the EKS Pod Identity Agent add-on installed on the ArgoCD cluster.

Aspect IRSA Pod Identity
Trust policy principal OIDC federated identity pods.eks.amazonaws.com service
Service account annotation Required Not needed
OIDC provider setup Required Not required
ArgoCD must run on EKS No Yes

Management role trust policy

Replace the OIDC-based trust with:

{
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Service": "pods.eks.amazonaws.com" },
    "Action": ["sts:AssumeRole", "sts:TagSession"]
  }]
}

Pod identity associations

No service account annotation. Create an association for each ArgoCD service account instead:

aws eks create-pod-identity-association \
  --cluster-name <ARGOCD_CLUSTER_NAME> \
  --namespace argocd \
  --service-account argocd-application-controller \
  --role-arn arn:aws:iam::<ARGOCD_ACCOUNT_ID>:role/<ARGOCD_MANAGEMENT_ROLE>

aws eks create-pod-identity-association \
  --cluster-name <ARGOCD_CLUSTER_NAME> \
  --namespace argocd \
  --service-account argocd-server \
  --role-arn arn:aws:iam::<ARGOCD_ACCOUNT_ID>:role/<ARGOCD_MANAGEMENT_ROLE>