title | shortTitle | intro | versions | type | topics | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Configuring OpenID Connect in HashiCorp Vault |
OpenID Connect in HashiCorp Vault |
Use OpenID Connect within your workflows to authenticate with HashiCorp Vault. |
|
tutorial |
|
{% data reusables.actions.enterprise-github-hosted-runners %}
OpenID Connect (OIDC) allows your {% data variables.product.prodname_actions %} workflows to authenticate with a HashiCorp Vault to retrieve secrets.
This guide gives an overview of how to configure HashiCorp Vault to trust {% data variables.product.prodname_dotcom %}'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.
{% data reusables.actions.oidc-link-to-intro %}
{% data reusables.actions.oidc-security-notice %}
To use OIDC with HashiCorp Vault, you will need to add a trust configuration for the {% data variables.product.prodname_dotcom %} OIDC provider. For more information, see the HashiCorp Vault documentation.
To configure your Vault server to accept JSON Web Tokens (JWT) for authentication:
-
Enable the JWT
auth
method, and usewrite
to apply the configuration to your Vault. Foroidc_discovery_url
andbound_issuer
parameters, use {% ifversion ghes %}https://HOSTNAME/_services/token
{% else %}https://token.actions.githubusercontent.com
{% endif %}. 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="{% ifversion ghes %}https://HOSTNAME/_services/token{% else %}https://token.actions.githubusercontent.com{% endif %}" \ oidc_discovery_url="{% ifversion ghes %}https://HOSTNAME/_services/token{% else %}https://token.actions.githubusercontent.com{% endif %}"
{% ifversion ghec %} {% note %}
Note: If a unique issuer URL for an enterprise was set using the REST API (as described in "AUTOTITLE"), the values for
bound_issuer
andoidc_discover_url
must match that unique URL. For example, for an enterprise namedoctocat
that uses the unique issuer URL,bound_issuer
andoidc_discovery_url
must be set tohttps://token.actions.githubusercontent.com/octocat
.{% endnote %} {% endif %}
-
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
-
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
ttl
defines the validity of the resulting access token.- Ensure that the
bound_claims
parameter is defined for your security requirements, and has at least one condition. Optionally, you can also set thebound_subject
as well as thebound_audiences
parameter. - To check arbitrary claims in the received JWT payload, the
bound_claims
parameter contains a set of claims and their required values. In the above example, the role will accept any incoming authentication requests from therepo-name
repository owned by theuser-or-org-name
account. - To see all the available claims supported by {% data variables.product.prodname_dotcom %}'s OIDC provider, see "AUTOTITLE."
For more information, see the HashiCorp Vault documentation.
To update your workflows for OIDC, you will need to make two changes to your YAML:
- Add permissions settings for the token.
- Use the
hashicorp/vault-action
action to exchange the OIDC token (JWT) for a cloud access token.
{% data reusables.actions.oidc-deployment-protection-rules %}
To add OIDC integration to your workflows that allow them to access secrets in Vault, you will need to add the following code changes:
- Grant permission to fetch the token from the {% data variables.product.prodname_dotcom %} OIDC provider:
- The workflow needs
permissions:
settings with theid-token
value set towrite
. This lets you fetch the OIDC token from every job in the workflow.
- The workflow needs
- Request the JWT from the {% data variables.product.prodname_dotcom %} OIDC provider, and present it to HashiCorp Vault to receive an access token:
- You can use the
hashicorp/vault-action
action to fetch the JWT and receive the access token from Vault, or you could use the Actions toolkit to fetch the tokens for your job.
- You can use the
This example demonstrates how to use OIDC with the official action to request a secret from HashiCorp Vault.
{% data reusables.actions.oidc-permissions-token %}
{% note %}
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.
{% endnote %}
The hashicorp/vault-action
action receives a JWT from the {% data variables.product.prodname_dotcom %} 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.
<Vault URL>
: Replace this with the URL of your HashiCorp Vault.<Vault Namespace>
: Replace this with the Namespace you've set in HashiCorp Vault. For example:admin
.<Role name>
: Replace this with the role you've set in the HashiCorp Vault trust relationship.<Secret-Path>
: Replace this with the path to the secret you're retrieving from HashiCorp Vault. For example:secret/data/production/ci npmToken
.
jobs:
retrieve-secret:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Retrieve secret from Vault
uses: hashicorp/vault-action@v2.4.0
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 %}
Note:
- If your Vault server is not accessible from the public network, consider using a self-hosted runner with other available Vault auth methods. For more information, see "AUTOTITLE."
<Vault Namespace>
must be set for a Vault Enterprise (including HCP Vault) deployment. For more information, see Vault namespace.
{% endnote %}
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.
- Set the
exportToken
option totrue
(default:false
). This exports the issued Vault access token as an environment variable:VAULT_TOKEN
. - Add a step to call the Revoke a Token (Self) Vault API to revoke the access token.
jobs:
retrieve-secret:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Retrieve secret from Vault
uses: hashicorp/vault-action@v2.4.0
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: {% raw %}${{ env.VAULT_TOKEN }}{% endraw %}" \
<Vault URL>/v1/auth/token/revoke-self
{% data reusables.actions.oidc-further-reading %}