💻 Coding

GitHub Actions OIDC to AWS IAM Deploy Role Planner: Trust Policy, Permissions Boundary, Environment Protection Rules, and a Least Privilege Action Map

Design a GitHub Actions OIDC deploy path into AWS without long lived access keys: issuer and subject conditions, IAM role trust policy, permissions boundary, GitHub Environment protection rules, and a least privilege action map for the workflow jobs that deploy.

0.0
0Reviews
P
October 8, 2026

Prompt

Act as a cloud security engineer who wires GitHub Actions OIDC to AWS IAM deploy roles, writes tight trust policies, applies permissions boundaries, and locks production deploys behind GitHub Environment protection rules.

Inputs:
- GitHub org, repo, and branch or tag patterns that may deploy: [RepoAndRefs]
- AWS account ID, region, and target services the workflow touches (for example ECR, ECS, S3, CloudFront, Lambda): [AwsTargets]
- Environments (staging, production) and who may approve production: [EnvironmentsAndApprovers]
- Existing OIDC provider ARN in the account if any, else note create: [OidcProviderState]
- Permissions boundary policy name or ARN if your org requires one: [PermissionsBoundary]
- Output format: [Format]

Generate:
1. An OIDC issuer and audience checklist for GitHub Actions into AwsTargets account, including token claims you will condition on.
2. A trust policy JSON sketch for the deploy role: Federated principal, StringEquals on aud, StringLike on sub for RepoAndRefs, and separate conditions per EnvironmentsAndApprovers where staging vs production differ.
3. A permissions boundary recommendation tied to PermissionsBoundary: which deploy actions stay inside the boundary and which must never be granted to the role.
4. A least privilege action map: IAM actions per job step for AwsTargets services, with Deny notes for iam:CreateUser, wildcards on * besides required reads.
5. GitHub Environment protection rules: required reviewers, wait timer, deployment branch policy matching RepoAndRefs.
6. A workflow snippet outline (YAML structure only) showing permission id-token write, aws-actions/configure-aws-credentials role assumption, and environment: production on the deploy job.
7. A verification checklist: thumbprint or provider create, role assume test from a PR, CloudTrail proof of AssumedRoleWithWebIdentity, and key deletion if static keys existed.
8. A failure FAQ: invalid identity token, sub mismatch on fork PRs, and environment not matching job.

Constraints:
- Do not invent AWS account IDs, thumbprints, or exact managed policy ARNs; use placeholders and [confirm in AWS IAM console].
- Prefer OIDC over access keys. Plain operator tone. No em dashes.

Instructions

Replace every [bracket] with your details before running. Works on ChatGPT, Claude, and Gemini.

Generated Output

This image was generated using the prompt above.

GitHub Actions OIDC to AWS IAM Deploy Role Planner: Trust Policy, Permissions Boundary, Environment Protection Rules, and a Least Privilege Action Map - Result

Examples

Example Input

RepoAndRefs: github.com/acme-labs/payments-api; deploy from refs/heads/main and refs/tags/v*
AwsTargets: account 111122223333; us-east-1; ECR push, ECS service update on cluster pay-prod, S3 sync for OpenAPI static docs bucket
EnvironmentsAndApprovers: staging auto from main; production requires 2 reviewers from @acme-labs/sre
OidcProviderState: token.actions.githubusercontent.com provider already exists in the account
PermissionsBoundary: arn:aws:iam::111122223333:policy/OrgDeployBoundary
Format: trust policy sketch, action map, environment rules, workflow outline, checklist, FAQ

Example Output

1) OIDC CHECKLIST
- Issuer: https://token.actions.githubusercontent.com
- Audience: sts.amazonaws.com
- Condition on token.actions.githubusercontent.com:sub matching repo acme-labs/payments-api and ref
- Provider already exists: reuse [confirm provider ARN in IAM]

2) TRUST POLICY SKETCH (production role)
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Federated": "arn:aws:iam::111122223333: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:acme-labs/payments-api:ref:refs/heads/main",
          "repo:acme-labs/payments-api:ref:refs/tags/v*"
        ]
      }
    }
  }]
}
Staging role: same pattern but environment claim or separate role name gha-payments-staging [confirm if you also bind job_workflow_ref].

3) PERMISSIONS BOUNDARY
Attach OrgDeployBoundary to both roles. Inside boundary allow ecr:*, ecs:UpdateService, s3:PutObject on the docs bucket ARN only. Never grant iam:CreateAccessKey, iam:PassRole to arbitrary roles, or * on s3 beyond the docs bucket.

4) LEAST PRIVILEGE ACTION MAP
- Build job: ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:PutImage, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload on repo payments-api
- Deploy job: ecs:DescribeServices, ecs:UpdateService, iam:PassRole only for the ECS task execution role ARN [confirm]
- Docs job: s3:PutObject, s3:DeleteObject on arn:aws:s3:::pay-openapi-docs/*
Deny: iam:CreateUser, secretsmanager:GetSecretValue unless a named secret ARN is required later.

5) GITHUB ENVIRONMENT RULES
- staging: deployment branches = main; no required reviewers
- production: required reviewers = 2 from @acme-labs/sre; prevent self review; deployment branches = main and tags v*; wait timer 5 minutes optional

6) WORKFLOW OUTLINE
permissions: id-token: write, contents: read
jobs.deploy.environment: production
steps: checkout -> configure-aws-credentials (role-to-assume prod role ARN, aws-region us-east-1) -> ecs deploy action or aws CLI update-service
Never store AWS_ACCESS_KEY_ID in repo secrets for this path.

7) VERIFICATION
[ ] Provider present
[ ] Role trust assumes only from this repo refs
[ ] Boundary attached
[ ] Manual workflow_dispatch on staging succeeds; CloudTrail shows AssumedRoleWithWebIdentity
[ ] Delete any old static deploy keys

8) FAQ
- Invalid identity token: check aud and permissions id-token write
- Fork PR cannot assume prod: expected; do not widen sub to pull_request on forks
- Environment mismatch: job.environment name must equal the GitHub Environment with protection rules

Reviews (0)

Please login to leave a review.
Loading reviews...