Skip to main content
← Back to workflows

How to Use HashiCorp Vault Action

hashicorp/vault-action -
GitHub Action
v3.0.0
435
Contributors
Contributor - RichiCoder1Contributor - jasonodonnell
Categories
CICUBE ANALYTICS INSIGHTS
Engineering Velocity: 25% Team Time Lost to CI Issues
View Platform →
3.5h
Time Saved/Dev/Week
40%
Faster Releases
Click for next insight
Usage
jobs:
build:
steps:
- name: Import Secrets
id: import-se
uses: hashicorp/vault-action@v2

vault-action logo

vault-action

A GitHub Action that simplifies using HashiCorp Vault™ secrets as build variables.


This is just a good-to-be GitHub Action for making it possible to work with secrets within a CI/CD workflow securely. Integrating HashiCorp Vault into GitHub Actions guarantees the secure storage of secret information with seamless, quick retrievability. It pulls secrets from the HashiCorp Vault pretty conveniently and even goes in a read-only mode, so there is no fear of ever changing the state of the Vault without realizing it.

It can incorporate many methods, such as JWT with GitHub OIDC Tokens, AppRole, Token, and many others, depending on what fits our setup. Multiple secret requests can be used with the request and environment variable names set to others that are more legible and, therefore, easier to manage. This way, we would be assured that our secrets are well kept and well managed in a way that enhances security postures.

Use the Vault GitHub Action easily to pull the HashiCorp Vault secrets. Generally, it is read only and not used to modify the state of a vault.

How to Use Retrieved Secrets

Secrets retrieved from Vault are exposed as environment variables or as the output and consumed for subsequent steps. Example:

- name: Step after 'Import Secrets'
run: |
ACCESS_KEY_ID = "${{ env.AWS_ACCESS_KEY_ID }}"
SECRET_ACCESS_KEY = "${{ steps.import-secrets.outputs.AWS_SECRET_ACCESS_KEY }}"

Directly put the secret in your environment variables on your scripts, just to be safe in your manipulation of sensitive data.

If they are needed in some other format, they can also be written to a JSON file:

- name: Step following 'Import Secrets'
run: |
touch secrets.json
echo '${{ toJson(steps.import-secrets.outputs) }}' >> secrets.json

This way is good to use for secrets so it is in the format that other applications or scripts can consume.

Process Check

Authenticates well with any method of authentication

** JWT with GitHub OIDC Tokens: **

Establish trust between GitHub Actions Workflow and Vault using the OIDC provider feature provided by GitHub.

with:
url: https://vault.mycompany.com:8200
caCertificate: ${{ secrets.VAULT_CA_CERT }}
role: <Vault JWT Auth Role Name>
method: jwt
jwtGithubAudience: sigstore

This is done in a secured way of authenticating, using tokens generated by the GitHub OIDC provider.

AppRole: Authenticate with a pre-defined role.

with:
url: https://vault.mycompany.com:8200
caCertificate: ${{ secrets.VAULT_CA_CERT }}
method: approle
roleId: ${{ secrets.VAULT_ROLE_ID }}
secretId: ${{ secrets.VAULT_SECRET_ID }}

This authentication method uses the approved roles and the secret IDs whose roles are pre-determined and are securely administered.

Token: Authenticate using a Vault token.

with:
url: https://vault.mycompany.com:8200
caCertificate: ${{ secrets.VAULT_CA_CERT }}
token: ${{ secrets.VAULT_TOKEN }}

This is how to authenticate against Vault by default and is quite easily set up.

GitHub: Authenticate with the GitHub method of authentication.

with:
url: https://vault.mycompany.com:8200
caCertificate: ${{ secrets.VAULT_CA_CERT }}
method: github
githubToken: ${{ secrets.GITHUB_TOKEN }}

Comments in DevOps: A GitHub token with read:org is necessary for this functionality.

Kubernetes: Use the auth method for Kubernetes runners on a self-hosted Kubernetes.

with:
url: https://vault.mycompany.com:8200
caCertificate: ${{ secrets.VAULT_CA_CERT }}
method: kubernetes
role: <Vault Kubernetes Auth Role Name>
kubernetesTokenPath: /var/run/secrets/kubernetes.io/serviceaccount/token

*most favorable for the conditions you're having your GitHub Actions runners hosted in Kubernetes.

Using Important Syntax

The secrets parameter separates many requests for secrets by ;.

** Naked Key:** To fetch key npmToken from the path secret/data/ci with a value of somelongtoken from Vault:

with:
secrets: secret/data/ci npmToken

This syntax will simplify the ability to specify from what secrets we're pulling out of Vault.

Define output variable name: To Create an Environment Variable Name:

with:
secrets: secret/data/ci npmToken | NPM_TOKEN

You can specify environment variables of your choosing, making the naming detailed on these things.

Quite Some Secrets: Fetch a lot of secrets by taking in multi-line input:

with:
secrets: |
secret/data/ci/aws accessKey | AWS_ACCESS_KEY_ID ;
secret/data/ci/aws secretKey | AWS_SECRET_ACCESS_KEY

Fetching Multiple Secrets: Enables fetching of multiple secrets simultaneously, very good for complex workflows.

Adding Extra Headers

If you need to put extra headers into the Vault request, set extraHeaders:

with:
secrets: |
secret/data/ci/aws accessKey | AWS_ACCESS_KEY_ID ;
secret/data/ci/aws secretKey | AWS_SECRET_ACCESS_KEY
extraHeaders: |
X-Secure-Id: ${{ secrets.SECURE_ID }}
X-Secure-Secret: ${{ secrets.SECURE_SECRET }}

To achieve additional compliance/security requirements, more headers may be required—for example, authentication through firewall.

Running the HashiCorp Cloud Platform or the Vault Enterprise

For additional inputs and outputs to the GitHub Actions workflow when using HCP Vault or Vault Enterprise:

Namespace: If you will use secrets from a particular Vault namespace, you must provide it as a parameter named namespace.

with:
url: https://vault-enterprise.mycompany.com:8200
caCertificate: ${{ secrets.VAULT_CA_CERT }}
token: ${{ secrets.VAULT_TOKEN }}
namespace: admin
secrets: |
secret/data/ci/aws accessKey | AWS_ACCESS_KEY_ID ;
secret/data/ci/aws secretKey | AWS_SECRET_ACCESS_KEY ;
secret/data/ci npm_token

If you are an enterprise that is using multi-tenancy features in Vault Enterprise or HCP, getting namespaces set is critically essential.