1. Resources
  2. /
  3. Plugins
  4. /
  5. aws-assume-role-with-web-identity-buildkite-plugin

AWS assume-role-with-web-identity

A Buildkite plugin to assume-role-with-web-identity using a Buildkite OIDC token before running the build command.

[!IMPORTANT] You will need to configure an appropriate OIDC identity provider in your AWS account with a Provider URL of https://agent.buildkite.com and an Audience of sts.amazonaws.com. This can be automated with Terraform. Then you can create a role to be assumed.

Example

Use the plugin in your steps like this:

steps:
  - command: aws sts get-caller-identity
    plugins:
      - aws-assume-role-with-web-identity#v1.4.0:
          role-arn: arn:aws:iam::AWS-ACCOUNT-ID:role/SOME-ROLE

This will call buildkite-agent oidc request-token --audience sts.amazonaws.com and exchange the resulting token for AWS credentials which are then added into the environment so tools like the AWS CLI will use the assumed role.

Configuration

role-arn (required, string)

ARN of the IAM role this plugin should assume.

role-session-name (optional, string)

The value of the role-session-name to pass with the STS request. This value can be referred to in assume-role policy, and will be recorded in Cloudtrail.

Defaults to buildkite-job-${BUILDKITE_JOB_ID}.

role-session-duration (optional, integer)

An integer number of seconds that the assumed role session should last. Passed as the value of the duration-seconds parameter in the STS request.

Defaults to 3600 (via the AWS CLI).

session-tags (optional, array)

A list of claims supported in Buildkite OIDC tokens. When provided, the returned OIDC tokens will have the requested claims duplicated into AWS Session Tokens. These can then be checked in Conditions on the IAM Role Trist Policy.

Eg.

session-tags:
- organization_slug
- pipeline_slug
- build_branch

Defaults to “ (empty).

[!NOTE] session-tags requires buildkite-agent v3.83.0 or better

region (optional, string)

Exports AWS_REGION and AWS_DEFAULT_REGION with the value you set. If not set the values of AWS_REGION and AWS_DEFAULT_REGION will not be changed.

Note that and AWS_REGION is used by the AWS CLI v2 and most SDKs. AWS_DEFAULT_REGION is included for compatibility with older SDKs and CLI versions.

credential-name-prefix (optional, string)

The plugin supports a credential-name-prefix option to prefix the default AWS credential names with a specific string. This is useful when you have multiple AWS credentials in your environment and you want to avoid conflicts.

For example, by setting credential-name-prefix:MY_PREFIX_ the plugin will export MY_PREFIX_AWS_ACCESS_KEY_ID, MY_PREFIX_AWS_SECRET_ACCESS_KEY and MY_PREFIX_AWS_SESSION_TOKEN instead of the default AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN.

plugins:
  - aws-assume-role-with-web-identity#v1.4.0:
      credential-name-prefix:MY_PREFIX_

hook (optional, string)

The hook to run. Can be either environment (the default) or pre-command.

Useful for when using a plugin such as the artifacts plugin that runs as a pre-command hook, and you need that to run with the pipeline role before then assuming your IAM role like so:

    plugins:
      - artifacts#v1.9.4:
          download: "out/*"
      - aws-assume-role-with-web-identity#v1.4.0
          hook: pre-command
          role-arn: arn:aws:iam::111111111111:role/example-role

IAM Role Trust Policies

There are two main options for defining which Buildkite OIDC tokens are permitted to assume an IAM Role.

Without Session Tags

This is the default behaviour of this plugin. Given a Buildkite pipeline step like so:

steps:
  - command: aws sts get-caller-identity
    plugins:
      - aws-assume-role-with-web-identity#v1.4.0:
          role-arn: arn:aws:iam::111111111111:role/example-role

The following trust policy on the IAM role will permit a Buildkite Job to assume the role if:

  • The organization slug is ORG_SLUG
  • The pipeline slug is PIPELINE_SLUG
  • The build is for the main branch
  • The agent is using either of the two provided IP addresses
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::111111111111:oidc-provider/agent.buildkite.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "agent.buildkite.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "agent.buildkite.com:sub": "organization:ORG_SLUG:pipeline:PIPELINE_SLUG:ref:main:*"
                },
                "IpAddress": {
                    "aws:SourceIp": [
                        "AGENT_PUBLIC_IP_ONE",
                        "AGENT_PUBLIC_IP_TWO"
                    ]
                }

            }
        }
    ]
}

With Session Tags

Alternatively, the Buildkite pipeline step can include the session-tags option:

steps:
  - command: aws sts get-caller-identity
    plugins:
      - aws-assume-role-with-web-identity#v1.4.0:
          role-arn: arn:aws:iam::111111111111:role/example-role
          session-tags:
          - organization_slug
          - pipeline_slug
          - build_branch

This means the trust policy on the IAM role can implement the same conditions, but minimise reliance on the overloaded sub claim. Note that AWS requires the agent.buildkite.com:sub claim to be specified in cases where an IAM role’s trust policy uses federation with Buildkite OIDC.

For the conditions to pass and the role assumption to be approved, the OIDC token must:

  • Must match all 6 conditions (agent.buildkite.com:sub, agent.buildkite.com:aud, aws:RequestTag/organization_slug, aws:RequestTag/pipeline_slug aws:RequestTag/build_branch and aws:SourceIp). That is, they are checked with a logical AND
  • Can match aws:RequestTag/build_branch with either main or production. When multiple values are provided for a aws::RequestTag condition they are checked with a logical OR
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::111111111111:oidc-provider/agent.buildkite.com"
            },
            "Action": [
                "sts:AssumeRoleWithWebIdentity",
                "sts:TagSession"
            ],
            "Condition": {
                "StringLike": {
                    "agent.buildkite.com:sub": "organization:ORG_SLUG:pipeline:PIPELINE_SLUG:ref:main:*"
                },
                "StringEquals": {
                    "agent.buildkite.com:aud": "sts.amazonaws.com",
                    "aws:RequestTag/organization_slug": "ORG_SLUG",
                    "aws:RequestTag/pipeline_slug": "PIPELINE_SLUG",
                    "aws:RequestTag/build_branch": [
                      "main",
                      "production"
                    ]
                },
                "IpAddress": {
                    "aws:SourceIp": [
                        "AGENT_PUBLIC_IP_ONE",
                        "AGENT_PUBLIC_IP_TWO"
                    ]
                }
            }
        }
    ]
}

A useful pattern with session-tags is to request the organization_id and pipeline_id claims. These values are UUIDs that will never change, so they:

  • will continue to work even if an organization or pipeline is renamed
  • mitigate any risk of being reused by different organizations or pipelines in the future, should the intended organization or pipeline be deleted
steps:
  - command: aws sts get-caller-identity
    plugins:
      - aws-assume-role-with-web-identity#v1.4.0:
          role-arn: arn:aws:iam::111111111111:role/example-role
          session-tags:
          - organization_id
          - pipeline_id

AWS configuration with Terraform

If you automate your infrastructure with Terraform, the following configuration will setup a valid OIDC IdP in AWS — adapted from an example for using OIDC with EKS:

locals {
  agent_endpoint = "https://agent.buildkite.com"
}

data "tls_certificate" "buildkite-agent" {
  url = local.agent_endpoint
}

resource "aws_iam_openid_connect_provider" "buildkite-agent" {
  url = local.agent_endpoint

  client_id_list = [
    "sts.amazonaws.com",
  ]

  thumbprint_list = [
    data.tls_certificate.buildkite-agent.certificates[0].sha1_fingerprint,
  ]
}

The oidc request will set the audience and subject as follows:

  • Audience: sts.amazonaws.com
  • Subject: organization:<ORG_SLUG>:pipeline:<PIPELINE_SLUG>:ref:<BRANCH_REF>:commit:<BUILD_COMMIT>:step:<STEP_ID>

In addition to the aws_iam_openid_connect_provider the role being assumed should have a trust policy that can be defined like so. Be sure to replace the <ORG_SLUG> and/or <PIPELINE_SLUG> placeholders.

data "aws_iam_policy_document" "buildkite-oidc-assume-role-trust-policy" {
  statement {
    sid     = "BuildkiteAssumeRole"
    actions = ["sts:AssumeRoleWithWebIdentity"]

    principals {
      type        = "Federated"
      identifiers = [aws_iam_openid_connect_provider.buildkite-agent.arn]
    }
    condition {
      test     = "ForAnyValue:StringLike"
      variable = "agent.buildkite.com:sub"
      values   = [
        "organization:<ORG_SLUG>:pipeline:*", # Example: Allow any pipeline in the organization access
        "organization:<ORG_SLUG>:pipeline:<PIPELINE_SLUG>:*", # Example: Restrict access to a pipeline in the organization
      ]
    }

    condition {
      test     = "StringEquals"
      variable = "agent.buildkite.com:aud"
      values   = ["sts.amazonaws.com"]
    }
  }
}

Compatibility

Elastic StackAgent Stack K8sHosted (Mac)Hosted (Linux)Notes
⚠️⚠️k8s stack does not possess aws
Hosted agents require AWS credentials on machine to perform aws command
  • ✅ Fully supported (all combinations of attributes have been tested to pass)
  • ⚠️ Partially supported (some combinations cause errors/issues)
  • ❌ Not supported

The plugins listed on this webpage are provided for informational purposes only. They have not undergone any formal security review or assessment. While we strive to provide useful resources, we cannot guarantee the safety, reliability, or integrity of these plugins. Users are strongly advised to conduct their own security evaluations before downloading, installing, or using any plugin. By using these plugins, you acknowledge and accept any risks associated with their use. We disclaim any liability for any harm or damages arising from the use of the plugins listed.

Start turning complexity into an advantage

Create an account to get started with a 30-day free trial. No credit card required.

Buildkite Pipelines

Platform

  1. Pipelines
  2. Pipeline templates
  3. Public pipelines
  4. Test Engine
  5. Package Registries
  6. Mobile Delivery Cloud
  7. Pricing

Hosting options

  1. Self-hosted agents
  2. Mac hosted agents
  3. Linux hosted agents

Resources

  1. Docs
  2. Blog
  3. Changelog
  4. Webinars
  5. Plugins
  6. Case studies
  7. Events
  8. Migration Services
  9. Comparisons

Company

  1. About
  2. Careers
  3. Press
  4. Brand assets
  5. Contact

Solutions

  1. Replace Jenkins
  2. Workflows for AI/ML
  3. Testing at scale
  4. Monorepo mojo
  5. Bazel orchestration

Legal

  1. Terms of Service
  2. Acceptable Use Policy
  3. Privacy Policy
  4. Subprocessors
  5. Service Level Agreement

Support

  1. System status
  2. Forum
© Buildkite Pty Ltd 2025