Deploy on AWS using Bitbucket Pipelines OpenID Connect

In order to use OpenID Connect on AWS, you will need to configure Pipelines as a Web Identity Provider, create an IAM role, and configure the build to assume the created role prior to running your build.

Configure Bitbucket Pipelines as a Web Identity Provider on AWS

Web Identity Providers allow the system to receive an authentication token, and then use or exchange that token for temporary security credentials in AWS. These temporary security credentials map to an IAM role with permissions to use the resources in your AWS account. Learn more about Web Identity Providers from AWS

  1. Access AWS Identity and Access Management (IAM).

  2. Select Identity providers under the Access management heading on the left sidebar.

  3. Select the Add provider button.

  4. In the Configure provider section, select OpenID Connect.

  5. Add the Provider URL, that is displayed as an identity provider on OpenID Connect in Bitbucket, to the corresponding text field. The Provider URL is the secure OpenID Connect URL used for authentication requests.

  6. Select the Get thumbprint button to verify that the provider URL is unique and accurate.

  7. Add the Audience, that is displayed as an identity provider on OpenID Connect in Bitbucket, to the corresponding text field. The audience is the client ID issued by the Identity provider for your app.

  8. Select the Add provider button.

To verify the thumbprint, you can follow the steps for obtaining the root CA thumbprint for an OpenID Connect Identity Provider. The thumbprint obtained from OpenSSL should be:

1 a031c46782e6e6c662c2c87c76da9aa62ccabd8e

Create an Identity and Access Management (IAM) role

Follow the steps below to create a new IAM role that can be assumed by anyone using Bitbucket Pipelines with this OIDC provider.

The trusted entity for this role must be Web identity, which allows you to choose the provider created in the previous steps.

  1. Access AWS Identity and Access Management (IAM).

  2. Select Roles under the Access management heading on the left sidebar.

  3. Select Create role.

  4. Select Web identity as the type of trusted entity.

  5. Select the Identity provider dropdown and choose the identity provider created from your configuration above.

  6. Select the Audience dropdown and choose the audience created from your configuration above.

  7. Select Next: Permissions.

  8. Select the permission policy or policies from the list of permission policies to attach to you new role. You may need to search for the policy, if you do not see it on the current list.

  9. Select Next: Tags.

  10. Add any labels (tags), if necessary.

  11. Select Next: Review.

  12. On the Create role page, enter a Role name (required) and a Role description (if applicable).

  13. Select Create role.

Configure build to assume the created role

In this step, you are going to configure your build to the assume the role created in the previous step. You need to enable your BitbucketCI step to create a unique OIDC token that can be used to assume a role and request a temporary credential. This token is exposed as an environment variable BITBUCKET_STEP_OIDC_TOKEN.

Example of bitbucket-pipelines.yml file

1 2 3 4 5 6 7 8 9 10 11 12 image: amazon/aws-cli pipelines: default: - step: oidc: true script: - export AWS_REGION=us-west-2 - export AWS_ROLE_ARN=arn:aws:iam::XXXXXXXXXXXX:role/oidc-demo - export AWS_WEB_IDENTITY_TOKEN_FILE=$(pwd)/web-identity-token - echo $BITBUCKET_STEP_OIDC_TOKEN > $(pwd)/web-identity-token - aws s3 cp s3://bucket/XXXXXX ./XXXXXXX

The above code is an example of bitbucket-pipelines.yml file that assumes the role to request temporary credentials that can be used to access AWS resources.

Run your build

Now that you have configured Pipelines as a Web Identity Provider in AWS, created an IAM role within the Web Identity Provider, and configured your build to assume the created role, it is time to run your build.


Using claims in ID tokens to limit access to the IAM role in AWS

The above steps allow any repository under the workspace to assume the created role, and also allows anyone with the token to assume the role. This section shows you how to limit access even more than that.

Before we get started with the ways to request additional identity information from the authorization server using the access token, you need to have a better understanding of the payload of each token that will be used in the use cases below, for example allowing only a specific repository to assume the role.

Example of a generated token

1 eyJraWQiOiJ0ZXN0X2tpZCIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJ7MWRlNDg5YmUtY2U2YS00MmEwLWE4YzgtZWFkYmYxMTc0YWM3fTp7YmQ3MTU3NDAtYzk3MC00ODZiLWI2OGEtYjQyMWVjMmExZjhifTp7NzU5ZGUwYzYtZWFlZS00ZWFhLWI3YTYtYzUwN2VlYzc1OWE3fSIsImF1ZCI6ImFyaTpjbG91ZDpiaXRidWNrZXQ6OndvcmtzcGFjZVwvOTIyZTExOGMtZjM0Zi00MjI2LWE4OTctMGUwYWZiZWM1NTNkIiwic3RlcFV1aWQiOiJ7NzU5ZGUwYzYtZWFlZS00ZWFhLWI3YTYtYzUwN2VlYzc1OWE3fSIsImRlcGxveW1lbnRFbnZpcm9ubWVudCI6InRlc3RpbmciLCJpc3MiOiJodHRwczpcL1wvYXBpLmJpdGJ1Y2tldC5vcmdcLzIuMFwvd29ya3NwYWNlc1wvYmJjaXRlc3RcL3BpcGVsaW5lcy1jb25maWdcL2lkZW50aXR5XC9vaWRjIiwicmVwb3NpdG9yeVV1aWQiOiJ7MWRlNDg5YmUtY2U2YS00MmEwLWE4YzgtZWFkYmYxMTc0YWM3fSIsImJyYW5jaE5hbWUiOiJvaWRjLWRlbW8iLCJleHAiOjE1Nzg3NjIzMDAsImlhdCI6MTU3ODc0NzYwMCwicGlwZWxpbmVVdWlkIjoie2JlZTMyZjM1LTVkYzAtNDY3Ni05YWQxLTY1NzM2M2JlMGVkMH0iLCJ3b3Jrc3BhY2VVdWlkIjoiezkyMmUxMThjLWYzNGYtNDIyNi1hODk3LTBlMGFmYmVjNTUzZH0ifQ.kjY0g_gDrqb3SN2g0E5OdUgIfKv9bLaG6eBeCLo47pMmh7-Jkcd-_G9-jB9isOuIaF706n5M8kh8aqgYDypyM1Rof825u_GRUQNr-ZnaYKkaRQjWQVKv-i7mDL1Rdfb1EQZ2c7N-ol9s73Rwwp_JKYfEmARhJVHpKR9F6iyfZ4ni0FO8ExfQgNH6aZ2nIlKe8ru57lRARexoMSENqQC7iQZnr5SaEqsl8kDM9WWkzZ_ONLiQEqAu6UbA1ce9BqmyuS52rIw2iia7gyi_64iL5GvgpiaAJh5hnV6DRv8MafUB45WX50peX9hK9_N85kjLWiwzLB7HkdWEd3yNfmH05R120l31Pghdi07FBjViOs_w19lktGJ7gwGzsj686-9rN6UutqfrSUgf6CJTWgbIO8nLj4BIXKxojcjDOO6ULvhhmMwMjPqVqHOJFKWmF9rUUoxap-p3ezzzgGYfGeqpp65Vryf-A_1Q0X8t8o6Qm_QjihU9ucU1e_Bt2-f0HznZ

The following is the payload of the example token above. You can use jwt.io to read other parts (Header, Signature).

1 2 3 4 5 6 7 8 9 10 11 12 13 { "sub": "{1de489be-ce6a-42a0-a8c8-eadbf1174ac7}:{bd715740-c970-486b-b68a-b421ec2a1f8b}:{759de0c6-eaee-4eaa-b7a6-c507eec759a7}", "aud": "ari:cloud:bitbucket::workspace/922e118c-f34f-4226-a897-0e0afbec553d", "stepUuid": "{759de0c6-eaee-4eaa-b7a6-c507eec759a7}", "deploymentEnvironment": "testing", "iss": "https://api.bitbucket.org/2.0/workspaces/bbcitest/pipelines-config/identity/oidc", "repositoryUuid": "{1de489be-ce6a-42a0-a8c8-eadbf1174ac7}", "branchName": "oidc-demo", "exp": 1578762300, "iat": 1578747600, "pipelineUuid": "{bee32f35-5dc0-4676-9ad1-657363be0ed0}", "workspaceUuid": "{922e118c-f34f-4226-a897-0e0afbec553d}" }

Currently AWS allows only a set of claims to be used in the trust policy. Learn more about available keys for AWS web identity federation. Based on the available keys for AWS web identity federation, we generated the ‘sub’ claim with the information that can used to craft more strict trust policies.

The following explains how the generated ‘sub’ claim is formed and provides some examples.

1 2 3 4 {REPOSITORY_UUID}[:{ENVIRONMENT_UUID}]:{STEP_UUID} E.g. {1de489be-ce6a-42a0-a8c8-eadbf1174ac7}:{bd715740-c970-486b-b68a-b421ec2a1f8b}:{759de0c6-eaee-4eaa-b7a6-c507eec759a7} {1de489be-ce6a-42a0-a8c8-eadbf1174ac7}:{759de0c6-eaee-4eaa-b7a6-c507eec759a7}

ENVIRONMENT_UUID: This part shows up only if the step is assigned to a deployment environment. This part is very important for crafting strict policies per environment.

Allowing only a specific repository to assume the role

The following step shows you how to update your trust policy to allow only a specific repository to assume the role.

Edit role trust relationship

In this step, you are going to edit your role trust relationship to limit only tokens with “sub” claim that matches a repository to assume the role.

Highlights editing your role trust relationship to limit tokens with a repo sub claim

The following configuration does that after replacing all variables with your configuration:

1 2 3 4 5 6 7 8 9 10 11 12 { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::{AWS_ACCOUNT_NUMBER}:oidc-provider/api.bitbucket.org/2.0/workspaces/{WORKSPACE}/pipelines-config/identity/oidc" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringLike": { "api.bitbucket.org/2.0/workspaces/{WORKSPACE}/pipelines-config/identity/oidc:sub": "{REPO_UUID}:{*}" } } }

Allowing only requests from deployment steps to assume the role

The following step shows you how to update your trust policy to allow only deployment steps to assume the role.

Edit role trust relationship

In this step, you are going to edit your role trust relationship to limit only tokens with “sub” claim that matches deployment environments to assume the role.

Highlights editing your role trust relationship to limit tokens with an environment sub claim

The following configuration does that after replacing all variables with your configuration:

1 2 3 4 5 6 7 8 9 10 11 12 { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::{AWS_ACCOUNT_NUMBER}:oidc-provider/api.bitbucket.org/2.0/workspaces/{WORKSPACE}/pipelines-config/identity/oidc" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringLike": { "api.bitbucket.org/2.0/workspaces/{WORKSPACE}/pipelines-config/identity/oidc:sub": "{REPO_UUID}*:{ENVIRONMENT_UUID}:*" } } }

Allowing only requests from Bitbucket Pipelines IP range to assume the role

The following step shows you how to update your trust policy to allow only requests from IP ranges to assume the role.

Edit role trust relationship

In this step, you are going to edit your role trust relationship to limit only assume requests coming from Bitbucket Pipelines IP to assume the role.

Highlights editing your role trust relationship to limit tokens with IP ranges sub claim

For more information

Still need help?

The Atlassian Community is here for you.