CI/CD Deploy Role (GitHub Actions OIDC)
Let a GitHub Actions workflow assume a deploy role with no long-lived AWS access keys stored in CI.
Policy
Replace the placeholder ARNs (YOUR-BUCKET-NAME, ACCOUNT_ID, REGION, etc.) with your real resource identifiers before use.
{
"TrustPolicy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:YOUR-ORG/YOUR-REPO:ref:refs/heads/main"
}
}
}
]
}
}Why it's scoped this way
- No AWS access keys are stored as GitHub secrets — the workflow exchanges a short-lived GitHub-issued OIDC token for temporary AWS credentials via sts:AssumeRoleWithWebIdentity.
- The :sub condition is scoped to repo:YOUR-ORG/YOUR-REPO:ref:refs/heads/main — a PR from a fork, or a push to any other branch, cannot assume this role. Widening :sub to repo:YOUR-ORG/YOUR-REPO:* lets any branch (including attacker-controlled PR branches in some workflow configurations) assume it.
- The :aud condition pinned to sts.amazonaws.com prevents token confusion with other OIDC-consuming services.
Hardening it further
- Attach the narrowest identity policy this deploy actually needs (e.g. cdk deploy needs CloudFormation + the specific services the stack touches) — this template only shows the trust policy half.
- Prefer per-environment roles (deploy-dev, deploy-prod) with different trust conditions over one role for all branches/environments.
Paste your finished policy into the free AI-Powered IAM analyzer to catch anything you loosened while filling it in.
Related templates
Check your finished policy — free
Shieldly's AI-Powered analyzer flags privilege-escalation paths, wildcards, and risky PassRole in seconds. No signup, no AWS credentials. Also ships as CLI, VS Code extension, GitHub Action, and CDK Guard.
Amazon Web Services (AWS) is a trademark of Amazon.com, Inc. Shieldly is not affiliated with, endorsed by, or sponsored by Amazon Web Services.