Optimize Your CI/CD Pipeline
Get instant insights into your CI/CD performance and costs. Reduce build times by up to 45% and save on infrastructure costs.
jobs:
build:
steps:
- name: Import Secrets
id: import-se
uses: hashicorp/vault-action@v2
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.