1. Docs
  2. Pulumi Cloud
  3. OpenID
  4. OpenID Client
  5. Github

Configuring OpenID Connect for Github

    This document outlines the steps required to configure Pulumi to accept Github id_tokens to be exchanged by Organization access tokens

    Prerequisites

    • You must be an admin of your Pulumi organization.
    Please note that this guide provides step-by-step instructions based on the official provider documentation which is subject to change. For the most current and precise information, always refer to the official Github documentation.

    Register the OIDC issuer

    1. Navigate to OIDC Issuers under your Organization’s Settings and click on Register a new issuer.
    2. Name the issuer and complete the url: https://token.actions.githubusercontent.com Register Github
    3. Submit the form

    Conrigure the Authorization Policies

    1. Click on the issuer name
    2. Change the policy decision to Allow
    3. Change the token type to Organization
    4. Add a new rule and configure it to verify the token audience to match your github organization url: aud: https://github.com/octo-org. For further information about Github token claims refer to the official Github documentation. Github policy example
    5. Click on update

    Set up the Github Actions step to fetch the OIDC token

    - name: Fetch OIDC token
      run: |
        OIDC_GH_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL"  | jq -r '.value')
        echo "OIDC_GH_TOKEN=$OIDC_GH_TOKEN" >> $GITHUB_ENV    
    

    Set up the Github Actions step to exchange it for a Pulumi access token

    - name: Fetch Pulumi access token
      run: |
        PULUMI_ACCESS_TOKEN=$(curl -X POST  \
        -H 'Content-Type: application/x-www-form-urlencoded' \
        -d 'audience=urn:pulumi:org:ORG_NAME \
        -d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
        -d 'subject_token_type=urn:ietf:params:oauth:token-type:id_token' \
        -d 'requested_token_type=urn:pulumi:token-type:access_token:organization' \
        -d 'subject_token=${{ env.OIDC_GH_TOKEN }}' \
        https://api.pulumi.com/oauth/token | jq -r '.access_token')
        echo "::add-mask::$PULUMI_ACCESS_TOKEN"
        echo "PULUMI_ACCESS_TOKEN=$PULUMI_ACCESS_TOKEN" >> $GITHUB_ENV    
    

    Replace ORG_NAME with the right Pulumi organization

    Sample Github Actions workflow

    name: Pulumi UP
    on:
      workflow_dispatch:
    
    permissions:
      id-token: write
      contents: read
    
    jobs:
      run_cron_job:
        runs-on: ubuntu-20.04
        timeout-minutes: 30
    
        steps:
          - name: Checkout repo
            uses: actions/checkout@v3
    
          - name: Install pulumi
            uses: pulumi/actions@v4
    
          - name: Install deps
            run: yarn
    
          - name: Fetch OIDC token
            run: |
              OIDC_GH_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL"  | jq -r '.value')
              echo "OIDC_GH_TOKEN=$OIDC_GH_TOKEN" >> $GITHUB_ENV          
    
          - name: Fetch Pulumi access token
            run: |
              PULUMI_ACCESS_TOKEN=$(curl -X POST  \
                -H 'Content-Type: application/x-www-form-urlencoded' \
                -d 'audience=urn:pulumi:org:ORG_NAME' \
                -d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
                -d 'subject_token_type=urn:ietf:params:oauth:token-type:id_token' \
                -d 'requested_token_type=urn:pulumi:token-type:access_token:organization' \
                -d 'subject_token=${{ env.OIDC_GH_TOKEN }}' \
                https://api.pulumi.com/api/oauth/token | jq -r '.access_token')
              echo "::add-mask::$PULUMI_ACCESS_TOKEN"
              echo "PULUMI_ACCESS_TOKEN=$PULUMI_ACCESS_TOKEN" >> $GITHUB_ENV          
    
          - uses: pulumi/actions@v4
            with:
              command: up
              stack-name: ...
    
      Introducing Drift Detection, TTL Stacks, and Scheduled Deployments. Learn More.