1. Resources
  2. /
  3. Plugins
  4. /
  5. pulumi-oidc-buildkite-plugin

Pulumi OIDC Buildkite Plugin

A Buildkite plugin that exchanges a Buildkite OIDC token for a Pulumi access token using OAuth 2.0 Token Exchange.

The resulting token is exported as PULUMI_ACCESS_TOKEN, allowing subsequent pipeline steps to authenticate with Pulumi Cloud without storing static credentials.

Prerequisites

  • Buildkite agent v3.48+ (OIDC token support)
  • curl >= 8.0.0
  • jq >= 1.5 (for -e exit status flag)
  • bash >= 4.0
  • A Pulumi Cloud organization with OIDC configured (see setup below). Available token types depend on your Pulumi edition:
    • Individual: personal tokens only
    • Team: personal and organization tokens
    • Enterprise / Business Critical: personal, organization, and team tokens

Pulumi Cloud Setup

Before using this plugin, you need to register Buildkite as an OIDC issuer in Pulumi Cloud and create an authorization policy.

1. Register Buildkite as an OIDC Issuer

  1. Navigate to Pulumi Cloud > Access Management > Settings > OIDC Issuers
  2. Click Register a new issuer
  3. Set the issuer URL to https://agent.buildkite.com
  4. Configure the max token expiration as needed

See the Pulumi OIDC client documentation for details.

2. Create an Authorization Policy

By default, all token exchange requests are denied. You must create an authorization policy that matches the Buildkite OIDC token claims.

Buildkite OIDC tokens use the following subject claim format:

organization:{ORG_SLUG}:pipeline:{PIPELINE_SLUG}:ref:{REF}:commit:{COMMIT}:step:{STEP_KEY}

Example policy allowing all pipelines in a Buildkite organization:

  • Sub claim: organization:my-buildkite-org:pipeline:*:ref:*:commit:*:step:*
  • Token type: Organization access token
  • Scope: (leave empty for default)

Configuration

Required

org_name (string)

The Pulumi organization name. Used to construct the audience (urn:pulumi:org:<org_name>) for both the Buildkite OIDC token request and the Pulumi token exchange.

Optional

lifetime (number)

The lifetime (in seconds) for the Buildkite OIDC token before it expires. Must be a non-negative integer. When set to 0 (the default), the API uses its default lifetime.

Default: 0

requested_token_type (string)

The type of Pulumi access token to request. Must be one of:

ValueDescription
urn:pulumi:token-type:access_token:organizationOrganization-scoped token (default)
urn:pulumi:token-type:access_token:teamTeam-scoped token (requires scope)
urn:pulumi:token-type:access_token:personalPersonal token (requires scope)

Default: urn:pulumi:token-type:access_token:organization

scope (string)

Scope for the requested token. The value depends on the requested_token_type:

Token TypeScope FormatExample
Organizationadmin (optional, for admin privileges)admin
Teamteam:<TEAM_NAME>team:platform-team
Personaluser:<USER_LOGIN>user:jane

The authorization policy must explicitly grant the requested scope.

backend_url (string)

The Pulumi Cloud API base URL. Override this for self-hosted Pulumi Cloud deployments.

Default: https://api.pulumi.com

debug (boolean)

When true, prints the full curl command and API response for troubleshooting. Warning: this exposes both the Buildkite OIDC token and the Pulumi access token in the build log. Only use for debugging.

Default: false

Output

On success, the plugin exports:

  • PULUMI_ACCESS_TOKEN - A short-lived Pulumi access token that authenticates subsequent pulumi CLI commands.

Examples

Minimal: organization access token

steps:
  - label: ":pulumi: Deploy"
    command: "pulumi up --yes --stack my-org/my-stack/production"
    plugins:
      - instant-labs/pulumi-oidc#v0.1.0:
          org_name: "my-org"

Team-scoped access token

steps:
  - label: ":pulumi: Deploy"
    command: "pulumi up --yes --stack my-org/my-stack/production"
    plugins:
      - instant-labs/pulumi-oidc#v0.1.0:
          org_name: "my-org"
          requested_token_type: "urn:pulumi:token-type:access_token:team"
          scope: "team:platform-team"

Personal access token with custom lifetime

steps:
  - label: ":pulumi: Deploy"
    command: "pulumi up --yes --stack my-org/my-stack/production"
    plugins:
      - instant-labs/pulumi-oidc#v0.1.0:
          org_name: "my-org"
          requested_token_type: "urn:pulumi:token-type:access_token:personal"
          scope: "user:jane"
          lifetime: 3600

With Pulumi ESC for cloud credentials

After obtaining a Pulumi access token via this plugin, you can use Pulumi ESC to dynamically fetch cloud provider credentials:

steps:
  - label: ":pulumi: Deploy with ESC"
    commands:
      - eval $(pulumi env open my-org/my-project/aws-prod --format shell)
      - pulumi up --yes --stack my-org/my-stack/production
    plugins:
      - instant-labs/pulumi-oidc#v0.1.0:
          org_name: "my-org"

This uses your Pulumi access token to open an ESC environment that provides temporary AWS/Azure/GCP credentials via OIDC federation. See Configuring OIDC in ESC for environment setup.

References

Development

Run tests:

make test

Run linter:

make lint

License

MIT License. See LICENSE.

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 for free.

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
  10. CI/CD perspectives

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

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