CI/CD Security: Eliminating Long-lived Secrets with GitHub Actions OIDC

Security tutorial - IT technology blog
Security tutorial - IT technology blog

The “Secret Key Leak” Nightmare in CI/CD

Many DevOps Engineers still have the habit of creating an IAM User, granting Admin permissions, and pasting the AWS_ACCESS_KEY_ID pair directly into GitHub Secrets. While this makes workflows run immediately, it puts the system in an extremely dangerous position. A single moment of negligence resulting in exposed logs or lost GitHub access could put your entire Cloud infrastructure in the hands of bad actors.

In reality, companies have received AWS bills for tens of thousands of dollars overnight. Hackers often use leaked keys to spin up massive clusters of EC2 p3.16xlarge instances for crypto mining. Instead of using a permanent “master key,” OIDC (OpenID Connect) allows you to authenticate with Cloud providers through a trust relationship without storing any long-term secrets.

Why is OIDC Safer Than Traditional Methods?

The Old Way: Static Credentials

You create a User, generate a Key, and save it to GitHub. This method is simple but extremely risky.

  • Risk: Keys are valid indefinitely until you manually delete them.
  • Management: Manual key rotation is time-consuming and prone to system disruptions.

The Modern Way: OIDC (OpenID Connect)

GitHub Actions acts as an Identity Provider. When a workflow starts, GitHub issues a short-lived token valid for only a few minutes to AWS or GCP. The Cloud provider verifies this token and only allows command execution within a narrow scope.

  • Benefit: The token automatically expires after the workflow finishes.
  • Control: You can limit exactly which repo and branch are allowed to borrow permissions (Assume Role).

Why I Prioritize OIDC for Every Production Project

Peace of mind is the greatest value. You no longer have to worry about accidentally printing logs containing secrets or forgetting to rotate passwords for Service Accounts periodically. For manual administrative tasks requiring ultra-strong passwords, I often use the password generator at toolcraft.app. Then, I configure OIDC so that CI/CD runs fully automatically, completely removing the human element from key management.

3 Steps to Implement OIDC with AWS and GitHub Actions

Step 1: Set Up the Identity Provider on AWS

First, you need to tell AWS that GitHub is a trusted authentication source. Go to IAM Console -> Identity Providers -> Add provider.

  • Provider type: OpenID Connect
  • Provider URL: https://token.actions.githubusercontent.com
  • Audience: sts.amazonaws.com

Step 2: Configure IAM Role and Trust Policy

This is the key step to protecting your resources. You create a Role for GitHub Actions to “borrow.” The Trust Policy snippet below ensures that only your specific repository has the right to use this Role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:*"
        },
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}

Don’t forget to replace 123456789012 with your actual Account ID and my-org/my-repo with your repository information.

Step 3: Update the Workflow YAML

In the workflow file, you must add the id-token: write permission. Without this line, GitHub will not be able to generate the OIDC token to send to AWS.

permissions:
  id-token: write
  contents: read

jobs:
  Deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionRole
          aws-region: ap-southeast-1
      - run: aws s3 ls

Security Principles You Can’t Ignore

While OIDC is powerful, you still need to follow the “Least Privilege” principle. Never assign AdministratorAccess to a CI/CD Role. If you are only deploying an application to S3, only grant s3:PutObject and s3:ListBucket permissions.

Tighten the conditions in the Trust Policy by specifying the branch. For example: repo:username/repo-name:ref:refs/heads/main. This prevents someone from creating a side branch to run unauthorized workflows and tamper with Cloud resources. Good luck building a secure CI/CD system!

Share: