From 876cdcfdd3402f14a4a870391ade39d26e3176c4 Mon Sep 17 00:00:00 2001 From: Rosemary Wang <915624+joatmon08@users.noreply.github.com> Date: Mon, 28 Mar 2022 12:23:28 -0400 Subject: [PATCH] Update docs with GitHub OIDC token configuration (#301) --- README.md | 212 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 156 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index f9ce84f..8cfbf3f 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,21 @@ A helper action for easily pulling secrets from HashiCorp Vaultâ„¢. - [Vault GitHub Action](#vault-github-action) - [Example Usage](#example-usage) - - [Authentication method](#authentication-method) + - [Authentication Methods](#authentication-methods) + - [JWT with GitHub OIDC Tokens](#jwt-with-github-oidc-tokens) + - [AppRole](#approle) + - [Token](#token) + - [GitHub](#github) + - [JWT with OIDC Provider](#jwt-with-oidc-provider) + - [Kubernetes](#kubernetes) + - [Other Auth Methods](#other-auth-methods) - [Key Syntax](#key-syntax) - [Simple Key](#simple-key) - [Set Output Variable Name](#set-output-variable-name) - [Multiple Secrets](#multiple-secrets) - [Other Secret Engines](#other-secret-engines) - [Adding Extra Headers](#adding-extra-headers) - - [Vault Enterprise Features](#vault-enterprise-features) + - [HashiCorp Cloud Platform or Vault Enterprise](#hashicorp-cloud-platform-or-vault-enterprise) - [Namespace](#namespace) - [Reference](#reference) - [Masking - Hiding Secrets from Logs](#masking---hiding-secrets-from-logs) @@ -39,8 +46,8 @@ jobs: uses: hashicorp/vault-action@v2.3.1 with: url: https://vault.mycompany.com:8200 - token: ${{ secrets.VaultToken }} - caCertificate: ${{ secrets.VAULTCA }} + token: ${{ secrets.VAULT_TOKEN }} + caCertificate: ${{ secrets.VAULT_CA_CERT }} secrets: | secret/data/ci/aws accessKey | AWS_ACCESS_KEY_ID ; secret/data/ci/aws secretKey | AWS_SECRET_ACCESS_KEY ; @@ -48,87 +55,176 @@ jobs: # ... ``` -## Authentication method +## Authentication Methods -While most workflows will likely use a vault token, you can also use an `approle` to authenticate with Vault. You can configure which by using the `method` parameter: +Consider using a [Vault authentication method](https://www.vaultproject.io/docs/auth) such as the JWT auth method with +[GitHub OIDC tokens](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) or the AppRole auth method. You can configure which by using the `method` parameter. + +### JWT with GitHub OIDC Tokens + +You can configure trust between a GitHub Actions workflow +and Vault using the +[GitHub's OIDC provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). +Each GitHub Actions workflow receives an auto-generated OIDC token with claims +to establish the identity of the workflow. + +__Vault Configuration__ + +
+Click to toggle instructions for configuring Vault. + +Set up Vault with the [JWT auth method](https://www.vaultproject.io/api/auth/jwt#configure). +Pass the following parameters to your auth method configuration: + +- `oidc_discovery_url`: `https://token.actions.githubusercontent.com` +- `bound_issuer`: `https://token.actions.githubusercontent.com` + + +Configure a [Vault role](https://www.vaultproject.io/api/auth/jwt#create-role) for the auth method. + +- `role_type`: `jwt` + +- `bound_audiences`: `"http//github.com/"`. Update this parameter if + you change the `aud` claim in the GitHub OIDC token via the + `jwtGithubAudience` parameter in the action config. + +- `user_claim`: Set this to a claim name (e.g., `repository`) in the + [GitHub OIDC token](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token). + +- `bound_claims` OR `bound_subject`: match on [GitHub subject claims](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims). + + - For wildcard (non-exact) matches, use `bound_claims`. + + - `bound_claims_type`: `glob` + + - `bound_claims`: JSON object. Maps one or more claim names to corresponding wildcard values. + ```json + {"sub": "repo:/*"} + ``` + + - For exact matches, use `bound_subject`. + + - `bound_claims_type`: `string` + + - `bound_subject`: Must exactly match the `sub` claim in the OIDC token. + ```plaintext + repo::ref:refs/heads/branchName + ``` + +
+ +__GitHub Actions Workflow__ + +In the GitHub Actions workflow, the workflow needs permissions to read contents +and write the ID token. -- **token**: (by default) you must provide a `token` parameter ```yaml -... -with: - url: https://vault.mycompany.com:8200 - token: ${{ secrets.VaultToken }} - caCertificate: ${{ secrets.VAULTCA }} +jobs: + retrieve-secret: + permissions: + contents: read + id-token: write ``` -- **approle**: you must provide a `roleId` & `secretId` parameter + +In the action, provide the name of the Vault role you created to the `role` parameter. +You can optionally set the `jwtGithubAudience` parameter to change the `aud` +claim from its default. + ```yaml -... with: url: https://vault.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} + role: + method: jwt + jwtGithubAudience: sigstore # set the GitHub token's aud claim +``` + +### AppRole + +The [AppRole auth method](https://www.vaultproject.io/docs/auth/approle) allows +your GitHub Actions workflow to authenticate to Vault with a pre-defined role. +Set the role ID and secret ID as GitHub secrets and pass them to the +`roleId` and `secretId` parameters. + +```yaml +with: + url: https://vault.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} method: approle - roleId: ${{ secrets.roleId }} - secretId: ${{ secrets.secretId }} - caCertificate: ${{ secrets.VAULTCA }} + roleId: ${{ secrets.VAULT_ROLE_ID }} + secretId: ${{ secrets.VAULT_SECRET_ID }} ``` -- **github**: you must provide the github token as `githubToken` -**Notice: [Vault GitHub authentication](https://www.vaultproject.io/docs/auth/github) +### Token + +For the default method of authenticating to Vault, +use a [Vault token](https://www.vaultproject.io/docs/concepts/tokens). +Set the Vault token as a GitHub secret and pass +it to the `token` parameter. + +```yaml +with: + url: https://vault.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} + token: ${{ secrets.VAULT_TOKEN }} +``` + +### GitHub + +The [GitHub auth method](https://www.vaultproject.io/docs/auth/github) requires `read:org` permissions for authentication. The auto-generated `GITHUB_TOKEN` created for projects does not have these permissions and GitHub does not allow this token's permissions to be modified. A new GitHub Token secret must be created with -`read:org` permissions to use this authentication method.** +`read:org` permissions to use this authentication method. + +Pass the GitHub token as a GitHub secret into the `githubToken` parameter. ```yaml -... with: url: https://vault.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} method: github - githubToken: ${{ secrets.MY_GITHUB_TOKEN }} - caCertificate: ${{ secrets.VAULTCA }} + githubToken: ${{ secrets.GITHUB_TOKEN }} ``` -- **jwt**: (Github OIDC) you must provide a `role` parameter, additionally you can pass `jwtGithubAudience` parameter. + +### JWT with OIDC Provider + +You can configure trust between your own OIDC Provider and Vault +with the JWT auth method. Provide a `role` & `jwtPrivateKey` parameters, +additionally you can pass `jwtKeyPassword` & `jwtTtl` parameters ```yaml -... with: url: https://vault.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} method: jwt - role: github-action -``` - -**Notice:** For Github provided OIDC token to work, the workflow should have `id-token: write` & `contents: read` specified in the `permissions` section of the workflow - -```yaml -... -permissions: - id-token: write - contents: read -... -``` - -- **jwt**: you must provide a `role` & `jwtPrivateKey` parameters, additionally you can pass `jwtKeyPassword` & `jwtTtl` parameters - -```yaml -... -with: - url: https://vault.mycompany.com:8200 - method: jwt - role: github-action + role: jwtPrivateKey: ${{ secrets.JWT_PRIVATE_KEY }} jwtKeyPassword: ${{ secrets.JWT_KEY_PASS }} jwtTtl: 3600 # 1 hour, default value ``` -- **kubernetes**: you must provide the `role` paramaters. You can optionally override the `kubernetesTokenPath` paramater for custom mounted serviceAccounts. Consider [kubernetes auth](https://www.vaultproject.io/docs/auth/kubernetes) when using self-hosted runners on Kubernetes: +### Kubernetes + +Consider the [Kubernetes auth method](https://www.vaultproject.io/docs/auth/kubernetes) +when using self-hosted runners on Kubernetes. You must provide the `role` parameter +for the Vault role associated with the Kubernetes auth method. +You can optionally override the `kubernetesTokenPath` parameter for +custom-mounted serviceAccounts. + ```yaml -... with: url: https://vault.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} method: kubernetes - role: ${{ secrets.KUBE_ROLE }} + role: + kubernetesTokenPath: /var/run/secrets/kubernetes.io/serviceaccount/token # default token path ``` -If any other method is specified and you provide an `authPayload`, the action will attempt to `POST` to `auth/${method}/login` with the provided payload and parse out the client token. +### Other Auth Methods + +If any other method is specified and you provide an `authPayload`, the action will +attempt to `POST` to `auth/${method}/login` with the provided payload and parse out the client token. ## Key Syntax @@ -165,7 +261,6 @@ steps: # Import config... - name: Sensitive Operation run: "my-cli --token '${{ steps.secrets.outputs.npmToken }}'" - ``` _**Note:** If you'd like to only use outputs and disable automatic environment variables, you can set the `exportEnv` option to `false`._ @@ -258,11 +353,16 @@ with: This will automatically add the `x-secure-id` and `x-secure-secret` headers to every request to Vault. -## Vault Enterprise Features +## HashiCorp Cloud Platform or Vault Enterprise + +If you are using [HCP Vault](https://cloud.hashicorp.com/products/vault) +or Vault Enterprise, you may need additional parameters in +your GitHub Actions workflow. ### Namespace -If you need to retrieve secrets from a specific Vault namespace, all that's required is an additional parameter specifying the namespace. +If you need to retrieve secrets from a specific Vault namespace, set the `namespace` +parameter specifying the namespace. In HCP Vault, the namespace defaults to `admin`. ```yaml steps: @@ -271,10 +371,10 @@ steps: uses: hashicorp/vault-action with: url: https://vault-enterprise.mycompany.com:8200 + caCertificate: ${{ secrets.VAULT_CA_CERT }} method: token - caCertificate: ${{ secrets.VAULTCA }} - token: ${{ secrets.VaultToken }} - namespace: ns1 + token: ${{ secrets.VAULT_TOKEN }} + namespace: admin secrets: | secret/ci/aws accessKey | AWS_ACCESS_KEY_ID ; secret/ci/aws secretKey | AWS_SECRET_ACCESS_KEY ;