Turn on oidc: true for the step, register Bitbucket Pipelines as a web identity provider in AWS IAM, create a role that trusts it, and let the step exchange its token for temporary credentials. Then tighten the trust policy, because the default can let any repository in the workspace assume the role.
How it works
Bitbucket's documentation describes three parts: set Pipelines up as a web identity provider in IAM, create a role, and have the build assume it. A step with oidc: true receives a unique token in the environment variable BITBUCKET_STEP_OIDC_TOKEN. The example writes that value to a file named by AWS_WEB_IDENTITY_TOKEN_FILE, and the AWS CLI exchanges it for temporary credentials. No long-lived key is stored in a variable.
pipelines:
branches:
main:
- step:
oidc: true
script:
- export AWS_REGION=us-east-1
- export AWS_ROLE_ARN=arn:aws:iam::111122223333:role/example
- echo "$BITBUCKET_STEP_OIDC_TOKEN" > /tmp/web-identity-token
- export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/web-identity-token
- aws sts get-caller-identity
The account number and role are placeholders.
The default is wide
The page states that by default the setup allows any repository under the workspace to assume the created role. That is rarely what you want for production. Tighten it with the sub claim.
| Pattern | What the page shows |
|---|---|
| One repository | Repository UUID followed by a wildcard |
| Deployment steps in a repository | Repository UUID, then an environment UUID segment |
| Pipelines IP ranges | A condition limiting requests to Pipelines addresses |
The sub claim is built from the repository UUID, an environment UUID that appears only if the step is assigned to a deployment environment, and the step UUID. Bitbucket notes that AWS allows only a set of claims in trust policies, so extra information is encoded into sub. The payload also carries branchName and workspaceUuid, but they may not be usable as AWS conditions.
Steps
- In IAM, add an OpenID Connect provider using the provider URL and audience from the Bitbucket page. Check the page for the thumbprint it lists.
- Create a role with Web identity as the trusted entity and attach least-privilege permissions.
- Edit the trust policy so the
subclaim matches your repository UUID, and for production the deployment environment UUID. - Put
oidc: trueon deploy steps only. - Delete old access keys from workspace and repository variables, then deactivate them in IAM.
- Test from a feature branch to confirm it cannot assume the production role.
Why short-lived credentials help
A stored access key works from anywhere, for as long as nobody rotates it. A key copied from a log, a laptop or a backup stays useful to whoever holds it. A token exchanged during a build gives AWS temporary credentials that expire on their own, tied to the repository and step that asked. If a build log leaks, the damage window is short. That is the practical reason to move, and it also removes a rotation chore from your list.
For variable scopes, see Bitbucket variable scopes and precedence. The same idea for another platform is in GitHub Actions OIDC with AWS.
Safeguard's policies and gates can add automated checks to changes before they merge, and you can try a free scan at https://gold.safeguard.sh/scan.
Quick check
Is the token itself a secret?
Treat it as one while the step runs. Anyone who can edit the step can print it.
Why bind to the deployment environment?
So a plain step in the same repository cannot assume the production role.
Sources
- Atlassian: Deploy on AWS using Bitbucket Pipelines OpenID Connect, fetched 19 October 2026.
Last reviewed: 19 October 2026.