Use OIDC to allow Github Actions to access Vault secrets

Anders Innovations
4 min readApr 4, 2022

by Joonas Venäläinen

Photo by Roman Synkevych 🇺🇦 on Unsplash

End of last year, Github made OIDC generally available for Github Actions. This means that you can configure your workflows to have access to auto-generated token and use it to request short-lived tokens from different providers that supports OIDC. This means more secure workflows as you no longer have to store the credentials as Github Secrets anymore. Before this change, the main authentication methods for Vault in Github have been the integrated Github authentication, Token, and AppRole. With these approaches excluding the Github authentication, you would still have to store credentials to Github Secrets to use them in workflows.

https://github.blog/2021-11-23-secure-deployments-openid-connect-github-actions-generally-available/

This post doesn’t detail how to set up Vault but instead expects that you already have Vault available to do these steps.

Enable the JWT auth method at gh-actions/

vault auth enable -path=gh-actions jwt

Add the needed trust configuration.

vault write auth/gh-actions/config \
oidc_discovery_url=”https://token.actions.githubusercontent.com" \
bound_issuer=”https://token.actions.githubusercontent.com"

Create a role that the workflow will then use to get the secrets. Replace the values <org> with your GitHub org/username and <repo> with the repository name you wish to set this up to

vault write auth/gh-actions/role/demo-role -<<EOF
{
“role_type”: “jwt”,
“user_claim”: “workflow”,
“bound_subject”: “”,
“bound_audiences”: “https://github.com/<org>",
“bound_claims_type”: “glob”,
“bound_claims”: {“sub”: [“repo:<org>/<repo>:ref:refs/tags/v*”]},
“policies”: “demo-ro”,
“ttl”: “1h”
}
EOF

Quickly going through a couple of the settings:

user_claim: This value will be used to identify this client in Vault uniquely. So this value would be populated with the workflow name.

bound_subject: This field would be used to match the subject to the claim. I want it to be empty as I will be using wildcard matching the tag using the bound_claims.

bound_audiences: This will identify the token recipient. By default, the aud value will be the repository owner URL.

bound_claims: Here we can define multiple claims if we want and also use wildcard matching. In this example, I’m using the tag as bound_claim.

policies: Which policies to assign for the role if authentication succeeds.

Create secret that will be accessed by the workflow

vault kv put secret/gh-demo demo_secret=hello

Now create the demo-ro policy that is allowed to read secrets from the gh-demo path

vault policy write demo-ro — << EOF
path “secret/data/gh-demo” {
capabilities = [“read”]
}
EOF

Now we have done all the setup on the Vault side and time to setup simple workflow that will get the secret from Vault

Most important part in the config is the permissions section where we are giving id-token write permission. This is needed to get OIDC token from workflow. Another permission is the contents which is needed by actions/checkout. Also note that this token is only available inside this job. If you want to make it available to all the jobs in the workflow define the permissions block at the top level outside jobs.

Remember to add VAULT_ADDR to Github Secrets.After this if you push tag eg. v1 to repository this workflow will be triggered and it should be able to get secret from Vault. This was just a simple demonstration what you can do with the OIDC token in the workflows. Here are couple of resources to get started building more advanced workflows:

General information about the OIDC token made available in the workflows

Example subject claims

Vault action used in the example

There is also Terraform module available that can be used to configure this per repository

--

--

Anders Innovations

Anders is a Finnish IT company, whose mission is sustainable software development with the greatest colleagues of all time.