---
title: GitHub
url: /docs/esc/guides/github-actions/
---
## Pulumi ESC GitHub Action

The [Pulumi ESC GitHub Action](https://github.com/marketplace/actions/esc-action) allows you to run ESC commands in your GitHub Actions workflows or inject secrets and configuration into your GitHub Actions workflows.

- Minimally, the GitHub action will download the Pulumi ESC CLI. If a `version` is specified, that version will be downloaded.
- Optionally, if an `environment` is passed in as an input, the action will inject all environment variables (specifically the keys under `values.environmentVariables` and projected files under `values.files`) from the environment into the current action/workflow environment.
- If specific keys are passed in using the `keys` input - only those keys will be injected into the GitHub Workflow.

## Authentication

Before using the Pulumi ESC GitHub Action, your workflow must authenticate with Pulumi Cloud. There are two supported approaches.

### OIDC (recommended)

The recommended approach uses OpenID Connect (OIDC) with the [`pulumi/auth-actions`](https://github.com/marketplace/actions/pulumi-auth-action) GitHub Action. Rather than storing a long-lived Pulumi access token as a repository secret, OIDC allows GitHub Actions to exchange a short-lived identity token for a scoped Pulumi access token at runtime.

Before you can use OIDC, you must configure Pulumi Cloud to trust GitHub Actions as an OIDC issuer. Follow the [Configuring OpenID Connect for GitHub](/docs/administration/access-identity/oidc-issuers/github/) guide to complete this one-time setup in your Pulumi organization.

Once that trust relationship is established, add the following permissions block to your workflow so that GitHub can issue OIDC tokens:

```yaml
permissions:
  id-token: write
  contents: read
```

Then include a `pulumi/auth-actions` step before any ESC action steps:

```yaml
- name: Authenticate with Pulumi Cloud
  uses: pulumi/auth-actions@v1
  with:
    organization: your-org
    requested-token-type: urn:pulumi:token-type:access_token:organization
```

The `id-token: write` permission is required for GitHub Actions to issue OIDC tokens to your workflow. The `requested-token-type` value determines the scope of the resulting Pulumi token; see [token types](/docs/administration/access-identity/oidc-issuers/#token-types-by-edition) for details on which types are available for your Pulumi edition.

### Access token

As an alternative to OIDC, you can authenticate with a long-lived [Pulumi access token](/docs/administration/access-identity/access-tokens/). Store the token as a repository secret and set it as the `PULUMI_ACCESS_TOKEN` environment variable in your workflow:

```yaml
env:
  PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
```

Long-lived access tokens are simpler to set up but require you to manage token rotation and ensure the token has appropriate permissions for your workflow.

## Example

This example shows how to inject all environment variables from the `tinyco/someProject/myEnv` environment into the GitHub Workflow from where it is called.

```yaml
on:
  - pull_request

permissions:
  id-token: write
  contents: read

jobs:
  test-all-key-injection:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v4
      - name: Authenticate with Pulumi Cloud
        uses: pulumi/auth-actions@v1
        with:
          organization: pulumi
          requested-token-type: urn:pulumi:token-type:access_token:organization
      - name: Install and inject ESC environment variables
        uses: pulumi/esc-action@v1
        with:
          environment: 'tinyco/someProject/myEnv'
      - name: Verify environment variables were injected
        run: |
          echo "Testing env injection..."
          echo "FOO=$FOO"
          echo "SOME_IMPORTANT_KEY=$SOME_IMPORTANT_KEY"
          echo "TEST_ENV=$TEST_ENV"
```

## Use cases

- **Injecting secrets into GitHub Actions**: The GitHub Action can be used to inject secrets into GitHub Actions workflows, allowing you to dynamically access your secrets from ESC as they are needed, rather than storing them in GitHub Secrets as long-lived static secrets. This allows you to leverage many of ESC's key features, such as automatic secret rotation and short-lived dynamic credentials and secrets and prevents secret sprawl.
- **Running ESC commands in GitHub Actions**: The GitHub Action can be used to run any arbitrary ESC commands in GitHub Actions workflows, beyond just injecting secrets. This allows you to use ESC as part of your CI/CD pipeline and create, update, or open environments automatically as part of your workflow.

## Importing secrets from GitHub Actions

If you have existing secrets in GitHub that you would like to import into ESC, you can run a one-time GitHub Action workflow like the following:

```yaml
name: Export secrets to ESC

on:
  - workflow_dispatch

permissions:
  id-token: write
  contents: read

jobs:
  export-to-esc:
    runs-on: ubuntu-latest
    name: Export GitHub secrets to ESC
    steps:
      - name: Install ESC CLI
        uses: pulumi/esc-action@v1
      - name: Authenticate with Pulumi Cloud
        uses: pulumi/auth-actions@v1
        with:
          organization: pulumi
          requested-token-type: urn:pulumi:token-type:access_token:organization
      - name: Export secrets to ESC
        run: |
          esc env get $ESC_ENVIRONMENT || esc env init $ESC_ENVIRONMENT
          echo "$GITHUB_SECRETS" | python3 -c 'import sys, yaml, json; j=json.loads(sys.stdin.read()); print(yaml.safe_dump({"values": {"environmentVariables": {name: {"fn::secret": value} for (name, value) in j.items() if name != "github_token"}}}))' | esc env edit $ESC_ENVIRONMENT -f -
        shell: bash
        env:
          ESC_ENVIRONMENT: myorg/myproject/myenvironment
          GITHUB_SECRETS: ${{ toJSON(secrets) }}
```

This workflow will export all GitHub secrets available to that repository into the specified ESC environment. You can run this workflow manually from the GitHub Actions UI.

