Configuring OpenID Connect in HashiCorp Vault

Use OpenID Connect within your workflows to authenticate with HashiCorp Vault.

Overview

OpenID Connect (OIDC) allows your GitHub Actions workflows to authenticate with a HashiCorp Vault to retrieve secrets.

This guide gives an overview of how to configure HashiCorp Vault to trust GitHub's OIDC as a federated identity, and demonstrates how to use this configuration in the hashicorp/vault-action action to retrieve secrets from HashiCorp Vault.

Prerequisites

Adding the identity provider to HashiCorp Vault

To use OIDC with HashiCorp Vault, you will need to add a trust configuration for the GitHub OIDC provider. For more information, see the HashiCorp Vault documentation.

To configure your Vault server to accept JSON Web Tokens (JWT) for authentication:

  1. Enable the JWT auth method, and use write to apply the configuration to your Vault.
    For oidc_discovery_url and bound_issuer parameters, use https://token.actions.githubusercontent.com. These parameters allow the Vault server to verify the received JSON Web Tokens (JWT) during the authentication process.

    vault auth enable jwt
    
    vault write auth/jwt/config \
      bound_issuer="https://token.actions.githubusercontent.com" \
      oidc_discovery_url="https://token.actions.githubusercontent.com"
    
  2. Configure a policy that only grants access to the specific paths your workflows will use to retrieve secrets. For more advanced policies, see the HashiCorp Vault Policies documentation.

    vault policy write myproject-production - <<EOF
    # Read-only permission on 'secret/data/production/*' path
    
    path "secret/data/production/*" {
      capabilities = [ "read" ]
    }
    EOF
    
  3. Configure roles to group different policies together. If the authentication is successful, these policies are attached to the resulting Vault access token.

    vault write auth/jwt/role/myproject-production -<<EOF
    {
      "role_type": "jwt",
      "user_claim": "actor",
      "bound_claims": {
        "repository": "user-or-org-name/repo-name"
      },
      "policies": ["myproject-production"],
      "ttl": "10m"
    }
    EOF
    

For more information, see the HashiCorp Vault documentation.

Updating your GitHub Actions workflow

To update your workflows for OIDC, you will need to make two changes to your YAML:

  1. Add permissions settings for the token.
  2. Use the hashicorp/vault-action action to exchange the OIDC token (JWT) for a cloud access token.

Note

When environments are used in workflows or in OIDC policies, we recommend adding protection rules to the environment for additional security. For example, you can configure deployment rules on an environment to restrict which branches and tags can deploy to the environment or access environment secrets. For more information, see Managing environments for deployment.

To add OIDC integration to your workflows that allow them to access secrets in Vault, you will need to add the following code changes:

This example demonstrates how to use OIDC with the official action to request a secret from HashiCorp Vault.

Adding permissions settings

The job or workflow run requires a permissions setting with id-token: write to allow GitHub's OIDC provider to create a JSON Web Token for every run.

Note

Setting id-token: write in the workflow’s permissions does not give the workflow permission to modify or write to any resources. Instead, it only allows the workflow to request (fetch) and use (set) an OIDC token for an action or step. This token is then used to authenticate with external services using a short-lived access token.

For detailed information on required permissions, configuration examples, and advanced scenarios, see OpenID Connect reference.

Note

When the permissions key is used, all unspecified permissions are set to no access, with the exception of the metadata scope, which always gets read access. As a result, you may need to add other permissions, such as contents: read. See Automatic token authentication for more information.

Requesting the access token

The hashicorp/vault-action action receives a JWT from the GitHub OIDC provider, and then requests an access token from your HashiCorp Vault instance to retrieve secrets. For more information, see the HashiCorp Vault GitHub Action documentation.

This example demonstrates how to create a job that requests a secret from HashiCorp Vault.

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
jobs:
  retrieve-secret:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Retrieve secret from Vault
        uses: hashicorp/vault-action@9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b
        with:
          method: jwt
          url: VAULT-URL
          namespace: VAULT-NAMESPACE # HCP Vault and Vault Enterprise only
          role: ROLE-NAME
          secrets: SECRET-PATH

      - name: Use secret from Vault
        run: |
          # This step has access to the secret retrieved above; see hashicorp/vault-action for more details.

Note

Revoking the access token

By default, the Vault server will automatically revoke access tokens when their TTL is expired, so you don't have to manually revoke the access tokens. However, if you do want to revoke access tokens immediately after your job has completed or failed, you can manually revoke the issued token using the Vault API.

  1. Set the exportToken option to true (default: false). This exports the issued Vault access token as an environment variable: VAULT_TOKEN.
  2. Add a step to call the Revoke a Token (Self) Vault API to revoke the access token.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
jobs:
  retrieve-secret:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Retrieve secret from Vault
        uses: hashicorp/vault-action@9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b
        with:
          exportToken: true
          method: jwt
          url: VAULT-URL
          role: ROLE-NAME
          secrets: SECRET-PATH

      - name: Use secret from Vault
        run: |
          # This step has access to the secret retrieved above; see hashicorp/vault-action for more details.

      - name: Revoke token
        # This step always runs at the end regardless of the previous steps result
        if: always()
        run: |
          curl -X POST -sv -H "X-Vault-Token: ${{ env.VAULT_TOKEN }}" \
            VAULT-URL/v1/auth/token/revoke-self

Further reading