Configure OpenID Connect for Bitbucket in AWS CDK


This guide will explain what is required to create a Bitbucket OpenID Connect (OIDC) provider in AWS CDK and includes a Bitbucket pipeline example on how to authenticate to AWS and access resources.

If you’re looking to configure OpenID Connect for GitHub, then read this article.

What is a Bitbucket OpenID Connect provider (OIDC)?

It’s an identity provider for BitBucket which uses the OpenID Connect protocol and can be set up on an AWS Account to establish trust between the account and your Bitbucket repository.

The advantage is that it allows you to access resources in AWS using an IAM role instead of using long-lived AWS credentials.

How to configure OpenID Connect for Bitbucket in AWS CDK

1. Create the Bitbucket OIDC provider

We’ll start by creating the OpenIdConnectProvider for Bitbucket:

const bitbucketDomain =
  'api.bitbucket.org/2.0/workspaces/<WORKSPACE>/pipelines-config/identity/oidc';

const bitbucketAudience =
  'ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1';

const bitbucketProvider = new iam.OpenIdConnectProvider(
  this,
  'bitbucketProvider',
  {
    url: `https://${bitbucketDomain}`,
    clientIds: [bitbucketAudience],
  }
);

To create the OIDC provider resource for Bitbucket we need to fill the following properties:

  • url: api.bitbucket.org/2.0/workspaces/<WORKSPACE>/pipelines-config/identity/oidc. Here you insert the Provider URL of the OpenID Connect URL used for authentication requests. Note: make sure to replace <WORKSPACE> with your own unique workspace name.
  • clientIds: ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1. This is the audience ID that is issued by the Identity Provider for your app.

You can find both the Provider URL and Audience ID in the OpenID Connect tab of your Bitbucket repository settings. For more details, check the official Bitbucket support page.

2. Create an IAM role with a WebIdentityPrincipal

Now we need to create an IAM role that is needed so we’ll be able to authenticate against the Bitbucket OIDC provider.

new iam.Role(this, 'exampleBitbucketDeployRole', {
  assumedBy: new iam.WebIdentityPrincipal(
    bitbucketProvider.openIdConnectProviderArn,
    conditions
  ),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
  ],
  roleName: 'exampleBitbucketDeployRole',
  description:
    'This role is used via Bitbucket pipelines to deploy with AWS CDK or Terraform on the customers AWS account',
  maxSessionDuration: cdk.Duration.hours(2),
});

To enable the IAM role to authenticate against the OIDC provider, we need to add the property iam.WebIdentityPrincipal and add the bitbucketProvider.openIdConnectProviderArn from the bitbucketProvider we created in the previous step.

The IAM role itself has no permissions by default, so we add a new property managedPolicies, and assign an AWS managed policy.

In this example, we apply the managed policy AdministratorAccess but you can limit the role’s privileges by assigning a custom or managed policy that contains fewer privileges.

The property maxSessionDuration sets a limit on how long the AWS STS credentials can be used at a time before expiring. In this case, the duration of the session with the STS credentials is set to 2 hours.

3. Create the condition for the IAM role and assign it to the WebIdentityPrincipal

In the previous part, we created the IAM role and as you can see we added conditions to the assumedBy property:

assumedBy: new iam.WebIdentityPrincipal(bitbucketProvider.openIdConnectProviderArn, conditions),

Now we’ll focus on creating the condition which will be attached to the iam.WebIdentityPrincipal. The condition is important because it allows us to limit the assumed role only to the Bitbucket repositories within the workspace.

We declare the following condition:

const bitbucketAudience =
  'ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1';

// grant only requests coming from a specific Bitbucket workspace.
const conditions: iam.Conditions = {
  StringEquals: {
    [`${bitbucketDomain}:aud`]: bitbucketAudience,
  },
};

The actual policy for the Web Identity will look like this when we synthesize the template in AWS CDK:

"AssumeRolePolicyDocument": {
  "Statement": [
    {
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "api.bitbucket.org/2.0/workspaces/<WORKSPACE>/pipelines-config/identity/oidc:aud": "ari:cloud:bitbucket::workspace/680cb3e455d4-f8b9b8d8f8d9-ddbb-4e19-baf1"
        }
      },
      "Effect": "Allow",
      "Principal": {
        "Federated": {
          "Ref": "bitbucketProviderE25A039A"
        }
      }
    }
  ],
  "Version": "2012-10-17"
},

4. Set up the bitbucket-pipelines.yml file

In order to create a CI/CD pipeline in Bitbucket, all you have to do is create a bitbucket-pipelines.yml at the root of your repository.

For this example, we’ll show how to set up the AWS credentials which we use to authenticate with the Bitbucket OIDC provider we created in AWS CDK at the beginning of this post.

image: node:16.3.0
pipelines:
  branches:
    main:
      - step:
          name: cdk deploy using oidc
          oidc: true
          script:
            - export AWS_REGION=eu-west-1
            - export AWS_ROLE_ARN=arn:aws:iam::012345678901:role/exampleBitbucketDeployRole
            - export AWS_WEB_IDENTITY_TOKEN_FILE=$(pwd)/web-identity-token
            - echo $BITBUCKET_STEP_OIDC_TOKEN > $(pwd)/web-identity-token
            - cdk deploy --app "ts-node openid-connect-bitbucket/main.ts" "*bitbucket-oidc" --require-approval never

If you plan on using this example then make sure to change the following values:

  • AWS_ROLE_ARN=arn:aws:iam::012345678901:role/exampleBitbucketDeployRole. Change the AWS account id of the role ARN which matches the account id where you deployed the Bitbucket OIDC provider.
  • AWS_REGION=eu-west-1. Change this to the region where you wish to run your cdk deploy command.
  • cdk deploy --app "ts-node openid-connect-bitbucket/main.ts" "*bitbucket-oidc" --require-approval never. This deploys the AWS CDK stack that is hosted on my aws-cdk-examples GitHub repository. Change this to your own custom AWS CDK stack.

Note: If you need more details I highly suggest reading the official Bitbucket documentation on how to set up the credentials for the pipeline.

Conclusion

You were able to successfully set up a Bitbucket OpenID Connect provider (OIDC) using AWS CDK TypeScript.

Additionally, you’ve also managed to test the OIDC connection in bitbucket pipelines by setting up and configuring the bitbucket-pipelines.yml file.

Everything that you’ve just built by following this article can also be found as a fully working example on my GitHub repository.

Elevate Your AWS CDK App with Expert Review & Guidance

Unlock the full potential of your AWS CDK app with our Expert AWS CDK App Code Review Service, conveniently delivered through AWS IQ.

Gain invaluable insights, minimize risks, and set a clear path forward for your project’s success.



Danny Steenman

A Senior AWS Cloud Engineer with over 9 years of experience migrating workloads from on-premises to AWS Cloud.

I have helped companies of all sizes shape their cloud adoption strategies, optimizing operational efficiency, reducing costs, and improving organizational agility.

Connect with me today to discuss your cloud aspirations, and let’s work together to transform your business by leveraging the power of AWS Cloud.

I need help with..
stacked cubes
Improving or managing my CDK App.Maximize the potential of your AWS CDK app by leveraging the expertise of a seasoned CDK professional.
Reducing AWS Costs.We can start by doing a thorough assessment of your current AWS infrastructure, identifying areas with potential for cost reduction and efficiency improvement.
Verifying if my infrastructure is reliable and efficient.We’ve created a comprehensive AWS Operations Checklist that you can utilize to quickly verify if your AWS Resources are set up reliably and efficiently.