In this tutorial, we will configure AWS and create a GitLab CI/CD job that lists all buckets using AWS CLI - all this without configuring authentication credentials in GitLab.
In enterprise CI/CD, exchanging a short-lived OIDC token for AWS STS credentials is far safer and more maintainable than defining AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY
as secret environment variables.
Using OIDC instead of static AWS keys means:
- No long-lived secrets to leak or rotate
- Context-scoped access (project/branch/environment)
- Auto-expiring STS tokens for a tiny attack window
- Precise audit trails tied to each pipeline/job
To get this to work, we need to complete 4 steps:
1. Add GitLab as an identity provider in AWS IAM
For this step, we will use the AWS console. Inside IAM, identify the menu item called "Identity providers".
From there, click on "Add provider", select OpenAI Connect, and fill in your public GitLab instance URL.
2. Configure an IAM role
An IAM role is a reusable set of AWS permissions that we "borrow" temporarily to perform actions without using permanent access keys.
From the menu, select Roles > Create role. The type needs to be "Web identity".
Select gitlab.com as an identity provider.
This role needs to be restricted to a specific GitLab group, but it can be narrowed down to a project as well.
Initially, I recommend you skip adding permissions.
I will name this role GitLabWebIdentityRole_MyGitLabProjects.
The policy generated will look like this:
Find the newly created policy in the list and open it. The ARN will be needed for the next step:
3. Create the .gitlab-ci.yml file
First of all, define the variable ROLE_ARN
and set it to the value of the ARN for the IAM role.
sts_test:
image:
name: amazon/aws-cli:2.27.35
entrypoint: [""]
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
script:
# this is split out for correct exit code handling
- >
aws_sts_output=$(aws sts assume-role-with-web-identity
--role-arn "${ROLE_ARN}"
--role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}"
--web-identity-token ${GITLAB_OIDC_TOKEN}
--duration-seconds 3600
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
--output text)
- export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $aws_sts_output)
- aws sts get-caller-identity
Even if you haven't set any permission policies to the role, the job should still succeed.
As you can see, the configuration is quite verbose, but it offers full control over every STS parameter (duration, session name, JSON parsing, exit‐code handling).
- Add permission policies
Open the role and add the policies that are needed for the job/project/group.
Top comments (0)