DEV Community

Cover image for Authenticate GitLab Pipelines to AWS with OIDC (No Static Keys πŸš€)
Vijay Mourya
Vijay Mourya

Posted on

Authenticate GitLab Pipelines to AWS with OIDC (No Static Keys πŸš€)

πŸš€ Goodbye Static AWS Keys, Hello GitLab OIDC

Be honest β€” have you ever stored AWS keys in GitLab CI/CD variables and then thought:

  • "What if someone leaks these keys?"
  • "How do I rotate them across projects?"

Yeah… we’ve all been there.

Luckily, AWS + GitLab have a much better way: OIDC authentication.

With OIDC, your GitLab jobs can request short-lived AWS credentials on the fly. No static keys. No rotation pain. More security. πŸŽ‰


πŸ—Ί The Big Picture

Here’s the 30-second flow of what happens when a GitLab pipeline hits AWS using OIDC:

OIDC auth flow


πŸ”‘ Why OIDC Rocks

  • Short-lived creds (expire ~1h, customizable TTL).
  • Scoped (repo + branch conditions).
  • No stored secrets.
  • Works with any GitLab repo.

βœ… Step 0 β€” Prerequisites

  • AWS account (IAM admin).
  • GitLab.com repo (works with self-hosted if OIDC enabled).
  • GitLab version 15.7+ (needed for id_tokens:).
  • AWS CLI v2 in your runner/job.
  • (Optional) Terraform for IaC.

πŸ— Step 1 β€” Add OIDC Identity Provider in AWS

πŸ‘‰ In IAM β†’ Identity providers β†’ Add:

  • Type: OpenID Connect
  • URL: https://gitlab.com (or self-hosted URL)
  • Audience: https://gitlab.com

Terraform snippet:

resource "aws_iam_openid_connect_provider" "gitlab" {
  url             = "https://gitlab.com"
  client_id_list  = ["https://gitlab.com"]
  thumbprint_list = ["9e99a48a9960b14926bb7f3b02e22da2b0ab7280"] # GitLab CA
}
Enter fullscreen mode Exit fullscreen mode

πŸ›‘ Step 2 β€” Create IAM Role + Trust Policy

Trust only the repo + branch you want. Example:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/gitlab.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "gitlab.com:aud": "https://gitlab.com",
          "gitlab.com:sub": "project_path:mygroup/myrepo:ref_type:branch:ref:main"
        }
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

βš™οΈ Step 3 β€” Ask for a Token in GitLab CI Job

In .gitlab-ci.yml:

deploy:
  image: amazon/aws-cli:2.15.0
  id_tokens:
    OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - aws sts assume-role-with-web-identity \
        --role-arn "arn:aws:iam::<ACCOUNT_ID>:role/gitlab-oidc-role" \
        --role-session-name "gl-$CI_PROJECT_ID-$CI_PIPELINE_ID" \
        --web-identity-token "$OIDC_TOKEN" \
        --duration-seconds 3600 > creds.json
    - export AWS_ACCESS_KEY_ID=$(jq -r .Credentials.AccessKeyId creds.json)
    - export AWS_SECRET_ACCESS_KEY=$(jq -r .Credentials.SecretAccessKey creds.json)
    - export AWS_SESSION_TOKEN=$(jq -r .Credentials.SessionToken creds.json)
    - aws sts get-caller-identity
Enter fullscreen mode Exit fullscreen mode

πŸ” Step 4 β€” Safer: Token File Method

Instead of exporting keys, use AWS SDK auto-assume:

deploy:
  image: amazon/aws-cli:2.15.0
  id_tokens:
    OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - echo "$OIDC_TOKEN" > /tmp/web_identity_token
    - export AWS_ROLE_ARN="arn:aws:iam::<ACCOUNT_ID>:role/gitlab-oidc-role"
    - export AWS_WEB_IDENTITY_TOKEN_FILE="/tmp/web_identity_token"
    - export AWS_ROLE_SESSION_NAME="gl-$CI_PROJECT_ID"
    - aws sts get-caller-identity
    - aws s3 ls s3://my-bucket
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Step 5 β€” Test & Tighten

  • Run pipeline β†’ check aws sts get-caller-identity.
  • Lock trust policy:

    • Allow only tags or release/*.
    • Use StringLike for wildcards.
  • Attach least-privilege IAM policies.


πŸ›  Troubleshooting

  • AccessDenied β†’ condition mismatch (aud or sub).
  • Verification key error β†’ wrong issuer URL.
  • Empty OIDC token β†’ forgot id_tokens: block.

πŸ”’ Best Practices

  • Prefer token-file method.
  • Scope trust (repo + ref).
  • Separate roles per env (dev/prod).
  • Audit with CloudTrail.

πŸŽ‰ Wrapping Up

You just kicked static AWS keys out of your GitLab pipelines.

βœ… Short-lived creds.
βœ… Branch/repo scoped trust.
βœ… No secret storage.

Now your team can deploy to AWS with confidence. πŸš€


Top comments (0)