Hardcoded secrets are out. Secure, federated identity-based workflows are in.
This guide walks you through how to deploy infrastructure using GitHub Actions and Terraform, authenticating into AWS (or other cloud providers) using OpenID Connect (OIDC), no long-lived credentials required.
Why This Matters
- No secrets in CI/CD: You don’t need to store AWS keys in GitHub.
- Short-lived credentials: OIDC issues scoped, temporary access tokens.
- Auditability and traceability: Requests are tied to GitHub job identity.
- Least privilege friendly: You can tightly scope what each workflow can do.
Architecture Overview
- GitHub Actions uses the OIDC standard to request a signed identity token.
- AWS IAM Role trusts GitHub’s OIDC provider and validates claims (e.g., repo name).
- The workflow assumes a role with
sts:AssumeRoleWithWebIdentity
. - Terraform deploys using the temporary credentials.
Step-by-Step Guide
1. Configure IAM Role in AWS
{
"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:sub": "repo:your-org/your-repo:ref:refs/heads/main"
}
}
}
]
}
2. Create the Role with Least Privilege
Assign only the Terraform actions needed (e.g., manage S3, EC2, IAM).
3. Enable OIDC in GitHub
- Go to your repository → Settings → Security → OIDC
- Click “Add Provider” if not enabled
4. Reference the Role in Your Workflow
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::ACCOUNT_ID:role/YourOIDCRole
aws-region: us-east-1
- name: Terraform Init & Apply
run: |
terraform init
terraform apply -auto-approve
Best Practices
- Use repo/environment scoping: Lock the IAM role to specific GitHub repos or branches.
- Don’t grant
*
permissions: Always follow least privilege for the assumed role. - Use Terraform backends like S3 + DynamoDB: For proper state locking and durability.
- Enable CloudTrail: Track who assumed what role and when.
Common Pitfalls
- OIDC claims don’t match the IAM trust policy
- GitHub job permissions missing
id-token: write
- Forgetting to enable the OIDC provider in AWS
Resources
StackProof uses this pattern across multiple environments, production, staging, even ephemeral preview deployments.