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.8.1:
          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.

audience (optional, string)

The audience (aud claim) requested in the Buildkite OIDC token. Passed as the value of the --audience parameter in the OIDC request.

Defaults to sts.amazonaws.com. Set a custom value when a role’s trust policy should require a specific audience — e.g. to scope a sensitive role so that a token minted for one role cannot be used to assume another (audience restriction). Note that the OIDC identity provider’s Audience list must include any custom value used.

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). When oidc-token-lifetime is not set, this value is also used as the OIDC token lifetime, capped at 7200 (2 hours), the maximum enforced by Buildkite.

oidc-token-lifetime (optional, integer)

An integer number of seconds that the buildkite oidc token should last. Passed as the value of the lifetime parameter in the OIDC request.

Defaults to 300 (via the BUILDKITE AGENT) unless role-session-duration is set, in which case it defaults to whichever is smaller: role-session-duration or 7200. Note: Buildkite enforces a maximum OIDC token lifetime of 7200 (2 hours) — values above this will be rejected.

session-tags (optional, array)

A list of Buildkite OIDC claims to also pass to AWS as session tags. Session tags are available in the role session as aws:PrincipalTag/<claim> condition keys which are useful for attribute-based access control, and are recorded in AWS CloudTrail. You don’t need session tags to restrict which pipelines can assume a role. Using session tags requires sts:TagSession in the role’s trust policy. See Using AWS session tags for details.

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.8.1:
      role-arn: arn:aws:iam::111111111111:role/example-role
      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.8.1:
          hook: pre-command
          role-arn: arn:aws:iam::111111111111:role/example-role

IAM Role Trust Policies

AWS reads a subset of the Buildkite OIDC claims directly from the token, so a role’s trust policy can restrict which Buildkite organizations and pipelines can assume it using agent.buildkite.com:<claim> condition keys. See OIDC with AWS in the Buildkite docs for a full walkthrough.

For example, given a Buildkite pipeline step like so:

steps:
  - command: aws sts get-caller-identity
    plugins:
      - aws-assume-role-with-web-identity#v1.8.1:
          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 job belongs to the organization ORG_SLUG with the UUID ORG_ID, and the pipeline PIPELINE_SLUG with the UUID PIPELINE_ID:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::111111111111:oidc-provider/agent.buildkite.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "agent.buildkite.com:sub": "organization:ORG_SLUG:pipeline:PIPELINE_SLUG:*"
                },
                "StringEquals": {
                    "agent.buildkite.com:aud": "sts.amazonaws.com",
                    "agent.buildkite.com:organization_slug": "ORG_SLUG",
                    "agent.buildkite.com:organization_id": "ORG_ID",
                    "agent.buildkite.com:pipeline_slug": "PIPELINE_SLUG",
                    "agent.buildkite.com:pipeline_id": "PIPELINE_ID"
                }
            }
        }
    ]
}
  • AWS requires a condition on agent.buildkite.com:sub in every trust policy for a Buildkite OIDC provider.

  • All conditions must match. To allow more than one value for a condition, list the values in an array, and any one of them can match. For example, this condition allows builds on either the main or production branch:

    "agent.buildkite.com:build_branch": ["main", "production"]
  • The organization_id and pipeline_id UUIDs never change and can’t be reused by another organization or pipeline.

  • The organization_slug and pipeline_slug conditions are optional, and make it easier to see which organization and pipeline the policy applies to. If you include them, renaming the organization or pipeline causes role assumption to fail until you update the policy.

  • For restricting access to a set of IP addresses, see Step 2 of OIDC with AWS.

  • For a complete list of supported condition keys, see Restricting access with Buildkite OIDC claims.

  • The cluster_id and cluster_name condition keys require optional claims. See Optional claims.

Optional claims

Optional claims, such as cluster_id and cluster_name, are only included in the OIDC token when requested. To request them, set the BUILDKITE_OIDC_TOKEN_CLAIMS environment variable on the step. The buildkite-agent oidc request-token command that this plugin runs reads this variable as its --claim option. Separate multiple claims with commas.

steps:
  - label: ":aws: assume role with OIDC claim conditions"
    command: aws sts get-caller-identity
    env:
      BUILDKITE_OIDC_TOKEN_CLAIMS: cluster_id
    plugins:
      - aws-assume-role-with-web-identity#v1.8.1:
          role-arn: arn:aws:iam::123456789123:role/placeholder-role

Without these claims in the token, trust policies using agent.buildkite.com:cluster_id or agent.buildkite.com:cluster_name conditions will deny role assumption.

Session tags

You don’t need session-tags to restrict which pipelines can assume a role. Use them when you need claim values in the role session, for example, in aws:PrincipalTag/<claim> conditions for attribute-based access control, or in AWS CloudTrail records. The role’s trust policy must also allow sts:TagSession. See Using AWS session tags for details.

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,
  ]
}

By default, the OIDC token that this plugin requests has the following audience and subject, which the trust policy below matches:

  • Audience: sts.amazonaws.com, unless you set the plugin’s audience option
  • Subject: organization:<ORG_SLUG>:pipeline:<PIPELINE_SLUG>:ref:<REF>:commit:<BUILD_COMMIT>:step:<STEP_KEY>, where <REF> is a Git ref such as refs/heads/main

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>, <ORG_ID>, <PIPELINE_SLUG> and <PIPELINE_ID> 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     = "StringLike"
      variable = "agent.buildkite.com:sub"
      values   = ["organization:<ORG_SLUG>:pipeline:<PIPELINE_SLUG>:*"]
    }

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

    condition {
      test     = "StringEquals"
      variable = "agent.buildkite.com:organization_slug"
      values   = ["<ORG_SLUG>"]
    }

    condition {
      test     = "StringEquals"
      variable = "agent.buildkite.com:organization_id"
      values   = ["<ORG_ID>"]
    }

    condition {
      test     = "StringEquals"
      variable = "agent.buildkite.com:pipeline_slug"
      values   = ["<PIPELINE_SLUG>"]
    }

    condition {
      test     = "StringEquals"
      variable = "agent.buildkite.com:pipeline_id"
      values   = ["<PIPELINE_ID>"]
    }
  }
}

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.

You deserve better CI.

Get started for free with a full month of our all-access trial.

Buildkite Pipelines

Platform

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

Hosting options

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

Resources

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

Company

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

Solutions

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

Compare

  1. Buildkite vs GitHub Actions
  2. Buildkite vs Jenkins
  3. Buildkite vs CircleCI
  4. Buildkite vs Harness
  5. Buildkite vs CloudBees
  6. Buildkite vs Blacksmith
  7. Buildkite vs Depot

Legal

  1. Terms of Service
  2. Acceptable Use Policy
  3. Privacy Policy
  4. Subprocessors
  5. Service Level Agreement
  6. Supplier Code of Conduct
  7. Modern Slavery Statement

Support

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