hashicorp/vault-action
Pull HashiCorp Vault secrets into a workflow, ideally via keyless JWT/OIDC auth.
What it does
hashicorp/vault-action logs in to a Vault server and retrieves a semicolon-separated list of secrets, exporting each as an environment variable (and masking it in logs) for later steps.
It supports many auth methods (token, approle, jwt, userpass, ldap, kubernetes); the jwt method uses the GitHub OIDC token so no Vault credential is stored in GitHub.
Usage
permissions:
id-token: write
contents: read
steps:
- uses: hashicorp/vault-action@v4
with:
url: https://vault.example.com:8200
method: jwt
role: github-actions
secrets: |
secret/data/ci npm_token | NPM_TOKEN ;
secret/data/ci deploy_key | DEPLOY_KEY
- run: ./deploy.sh # NPM_TOKEN and DEPLOY_KEY are in the envInputs
| Input | Description | Default | Required |
|---|---|---|---|
url | The URL for the Vault endpoint. | - | Yes |
secrets | A semicolon-separated list of secrets to retrieve, converted to environment variable keys. | - | No |
method | The auth method to use to authenticate with Vault. | token | No |
role | Vault role for the specified auth method. | - | No |
path | The Vault path for the auth method. | - | No |
token | The Vault token to be used to authenticate with Vault. | - | No |
exportEnv | Whether to export secrets as environment variables. | true | No |
jwtGithubAudience | The "aud" claim the OIDC JWT is intended for. | - | No |
Notes
The jwt method needs permissions: id-token: write and a Vault JWT auth backend configured to trust token.actions.githubusercontent.com, with bound claims restricting which repos can log in.
KV v2 paths include /data/ in the selector (secret/data/ci), a common trip-up coming from the CLI syntax.
Each secret is also available as a step output, and every retrieved value is automatically masked in logs.
Common errors
- A Vault
permission denied(403) means the login succeeded but the token policy does not grant read on the requested path, or, for jwt auth, the bound claims reject this repo/branch. - A 404 on a KV v2 secret usually means the
/data/segment is missing from the path insecrets.
Security and pinning
- Use the jwt (OIDC) method instead of a long-lived
tokensecret, and bind the Vault role to specific repositories and branches via bound claims. - Keep
exportTokenoff unless a later step genuinely needs the Vault token, and scope the role policy to read-only on the exact secret paths.
Alternatives and related
Frequently asked questions
How do I rename the environment variable a secret is exported as?
secrets: secret/data/ci npm_token | NPM_TOKEN exports that field as NPM_TOKEN instead of the auto-generated name.