|
1 | 1 | # Terraform Module: Hashicorp Vault GitHub OIDC <!-- omit in toc --> |
2 | 2 |
|
3 | | - |
4 | | - |
| 3 | + |
| 4 | +[](https://github.com/digitalocean/terraform-vault-github-oidc/actions/workflows/oidc_test.yaml) |
| 5 | + |
5 | 6 | [](https://bestpractices.coreinfrastructure.org/projects/6305) |
6 | | - |
7 | | - |
| 7 | + |
| 8 | + |
8 | 9 |
|
9 | 10 | Terraform module to configure Vault for GitHub OIDC authentication from Action runners on GitHub.com or self-hosted GitHub Enterprise Server. |
10 | 11 |
|
11 | 12 | OIDC authentication allows us to bind GitHub repositories (and subcomponents of a repository, such as a branch, ref, or environment) |
12 | 13 | to a Vault role without needing to manage actual credentials that require a lifecycle system, integration into repo-level |
13 | 14 | GitHub Secrets, or other organizational glue. |
14 | 15 |
|
| 16 | +Explore GitHub OIDC and HashiCorp Vault use cases with this hands-on workshop: <https://github.com/artis3n/course-vault-github-oidc>. |
| 17 | + |
15 | 18 | Reference documents that help with understanding the process: |
16 | 19 | - <https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault> |
17 | 20 |
|
18 | 21 | Once OIDC authentication is configured on a Vault server via this module, a GitHub repository can leverage |
19 | 22 | [hashicorp/vault-action](https://github.com/hashicorp/vault-action) to retrieve secrets from Vault with GitHub OIDC authentication. |
20 | | -No credential management needed! |
| 23 | +No secrets or credential management needed! |
21 | 24 |
|
22 | 25 | e.g. |
23 | 26 |
|
24 | 27 | ```yml |
25 | 28 | - name: Import Secrets |
26 | | - uses: hashicorp/vault-action@v2.4.1 |
| 29 | + uses: hashicorp/vault-action@v2 |
27 | 30 | id: secrets |
28 | 31 | with: |
29 | 32 | exportEnv: false |
|
40 | 43 |
|
41 | 44 | - [Usage](#usage) |
42 | 45 | - [Examples](#examples) |
| 46 | + - [Considerations for Enterprise Cloud organizations](#considerations-for-enterprise-cloud-organizations) |
43 | 47 | - [Variables](#variables) |
44 | | - - [oidc_bindings](#oidc_bindings) |
45 | | - - [oidc_bindings.audience](#oidc_bindingsaudience) |
46 | | - - [oidc_bindings.vault_role_name](#oidc_bindingsvault_role_name) |
47 | | - - [oidc_bindings.bound_subject](#oidc_bindingsbound_subject) |
48 | | - - [oidc_bindings.vault_policies](#oidc_bindingsvault_policies) |
49 | | - - [oidc_bindings.user_claim](#oidc_bindingsuser_claim) |
50 | | - - [oidc_bindings.additional_claims](#oidc_bindingsadditional_claims) |
51 | | - - [oidc_bindings.ttl](#oidc_bindingsttl) |
52 | | - - [default_ttl](#default_ttl) |
53 | | - - [default_user_claim](#default_user_claim) |
54 | | - - [oidc_auth_backend_path](#oidc_auth_backend_path) |
55 | | - - [github_identity_provider](#github_identity_provider) |
| 48 | + - [oidc\_bindings](#oidc_bindings) |
| 49 | + - [oidc\_bindings.audience](#oidc_bindingsaudience) |
| 50 | + - [oidc\_bindings.vault\_role\_name](#oidc_bindingsvault_role_name) |
| 51 | + - [oidc\_bindings.bound\_subject](#oidc_bindingsbound_subject) |
| 52 | + - [oidc\_bindings.vault\_policies](#oidc_bindingsvault_policies) |
| 53 | + - [oidc\_bindings.user\_claim](#oidc_bindingsuser_claim) |
| 54 | + - [oidc\_bindings.additional\_claims](#oidc_bindingsadditional_claims) |
| 55 | + - [oidc\_bindings.ttl](#oidc_bindingsttl) |
| 56 | + - [default\_ttl](#default_ttl) |
| 57 | + - [default\_user\_claim](#default_user_claim) |
| 58 | + - [oidc\_auth\_backend\_path](#oidc_auth_backend_path) |
| 59 | + - [github\_identity\_provider](#github_identity_provider) |
| 60 | + - [token\_type](#token_type) |
56 | 61 | - [Requirements](#requirements) |
57 | 62 | - [Providers](#providers) |
58 | 63 | - [Modules](#modules) |
@@ -86,8 +91,6 @@ You can find several examples leveraging this module under `examples/`: |
86 | 91 | - [Adding custom additional claims per OIDC binding](/examples/additional-claims) |
87 | 92 | - [Leveraging this module on-prem with GitHub Enterprise Server](/examples/github-enterprise) |
88 | 93 |
|
89 | | -There is another example run in the CI suite at [`test/terratest/configure-oidc/main.tf`](test/terratest/configure-oidc/main.tf). |
90 | | - |
91 | 94 | Basic example - one repo, separating secrets access by nonprod and prod pipelines. |
92 | 95 |
|
93 | 96 | ```terraform |
@@ -140,6 +143,12 @@ data "vault_policy_document" "deployment" { |
140 | 143 | } |
141 | 144 | ``` |
142 | 145 |
|
| 146 | +## Considerations for Enterprise Cloud organizations |
| 147 | + |
| 148 | +Enterprise Cloud organizations should strongly consider enabling the [Unique Token URL](https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#switching-to-a-unique-token-url) feature for their organization. |
| 149 | + |
| 150 | +If they do so, they should set the `github_identity_provider` variable of this module to their enterprise's unique token URL. |
| 151 | + |
143 | 152 | ## Variables |
144 | 153 |
|
145 | 154 | ### oidc_bindings |
@@ -297,13 +306,27 @@ You cannot pass in a Terraform reference to an existing backend. |
297 | 306 | **Optional** |
298 | 307 |
|
299 | 308 | By default, this role will communicate with github.com for an OIDC JWT (`https://token.actions.githubusercontent.com`). |
| 309 | + |
| 310 | +If you are an Enterprise Cloud customer, you should configure a [unique token URL](https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#switching-to-a-unique-token-url) and set this variable to your unique token URL. |
| 311 | + |
| 312 | +`https://token.actions.githubusercontent.com/<enterpriseSlug>` |
| 313 | + |
300 | 314 | If you run GitHub Enterprise Server, you will need to configure your instance of GitHub as the identity provider and should modify this variable. |
301 | 315 | This requires GitHub Enterprise Server version 3.5 or higher. |
302 | 316 |
|
303 | 317 | The format is: `https://HOSTNAME/_services/token`. |
304 | 318 |
|
305 | 319 | See <https://docs.github.com/en/enterprise-server@latest/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault#adding-the-identity-provider-to-hashicorp-vault>. |
306 | 320 |
|
| 321 | +### token_type |
| 322 | + |
| 323 | +**Optional** |
| 324 | + |
| 325 | +The type of Vault token that should be generated. |
| 326 | +<https://developer.hashicorp.com/vault/api-docs/auth/jwt#token_type> |
| 327 | + |
| 328 | +Because of the short TTLs and frequent use intended for authentication via this module, this module generates a [batch token](https://developer.hashicorp.com/vault/tutorials/tokens/batch-tokens) by default. |
| 329 | + |
307 | 330 | <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> |
308 | 331 | ## Requirements |
309 | 332 |
|
@@ -336,8 +359,9 @@ No modules. |
336 | 359 | | <a name="input_oidc_bindings"></a> [oidc\_bindings](#input\_oidc\_bindings) | A list of OIDC JWT bindings between GitHub repos and Vault roles. For each entry, you must include:<br><br> `audience`: By default, this must be the URL of the repository owner (e.g. `https://github.com/digitalocean`). This can be customized with the `jwtGithubAudience` parameter in [hashicorp/vault-action](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault#requesting-the-access-token) . This is the bound audience (`aud`) field from [GitHub's OIDC token](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) .<br><br> `vault_role_name`: The name of the Vault role to generate under the OIDC auth backend.<br><br> `bound_subject`: This is what is set in the `sub` field from [GitHub's OIDC token](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) . The bound subject can be constructed from various filters, such as a branch, tag, or specific [environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) . See [GitHub's documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims) for examples.<br><br> `vault_policies`: A list of Vault policies you wish to grant to the generated token.<br><br> `user_claim`: **Optional**. This is how you want Vault to [uniquely identify](https://www.vaultproject.io/api/auth/jwt#user_claim) this client. This will be used as the name for the Identity entity alias created due to a successful login. This must be a field present in the [GitHub JWT token](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) . Defaults to the `default_user_claim` variable if not provided. Consider the impact on [reusable workflows](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/using-openid-connect-with-reusable-workflows#how-the-token-works-with-reusable-workflows) if you are thinking of changing this value from the default.<br><br> `additional_claims`: **Optional**. Any additional `bound_claims` to configure for this role. Claim keys must match a value in [GitHub's OIDC token](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) . Do not use this field for the `sub` claim. Use the `bound_subject` parameter instead.<br><br> `ttl`: **Optional**. The default incremental time-to-live for the generated token, in seconds. Defaults to the `default_ttl` value but can be individually specified per binding with this value. | <pre>list(object({<br> audience = string,<br> vault_role_name = string,<br> bound_subject = string,<br> vault_policies = set(string),<br> user_claim = optional(string),<br> additional_claims = optional(map(string)),<br> ttl = optional(number),<br> }))</pre> | n/a | yes | |
337 | 360 | | <a name="input_default_ttl"></a> [default\_ttl](#input\_default\_ttl) | The default incremental time-to-live for generated tokens, in seconds. | `number` | `300` | no | |
338 | 361 | | <a name="input_default_user_claim"></a> [default\_user\_claim](#input\_default\_user\_claim) | This is how you want Vault to [uniquely identify](https://www.vaultproject.io/api/auth/jwt#user_claim) this client. This will be used as the name for the Identity entity alias created due to a successful login. This must be a field present 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) . Consider the impact on [reusable workflows](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/using-openid-connect-with-reusable-workflows#how-the-token-works-with-reusable-workflows) if you are thinking of changing this value from the default. | `string` | `"job_workflow_ref"` | no | |
339 | | -| <a name="input_github_identity_provider"></a> [github\_identity\_provider](#input\_github\_identity\_provider) | The JWT authentication URL used for the GitHub OIDC trust configuration. This should not be modified unless you are running GitHub Enterprise Server, in which case you should provide a URL in the format: `https://HOSTNAME/_services/token`. This requires GitHub Enterprise Server version 3.5 or higher. See <https://docs.github.com/en/enterprise-server@latest/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault#adding-the-identity-provider-to-hashicorp-vault>. | `string` | `"https://token.actions.githubusercontent.com"` | no | |
| 362 | +| <a name="input_github_identity_provider"></a> [github\_identity\_provider](#input\_github\_identity\_provider) | The JWT authentication URL used for the GitHub OIDC trust configuration. If you are an Enteprise Cloud account, you should configure a [unique token URL](https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#switching-to-a-unique-token-url) and set the result on this variable. If you are an Enterprise Server organization, you should provide a URL in the format: `https://HOSTNAME/_services/token`. This requires GitHub Enterprise Server version 3.5 or higher. See <https://docs.github.com/en/enterprise-server@latest/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault#adding-the-identity-provider-to-hashicorp-vault>. | `string` | `"https://token.actions.githubusercontent.com"` | no | |
340 | 363 | | <a name="input_oidc_auth_backend_path"></a> [oidc\_auth\_backend\_path](#input\_oidc\_auth\_backend\_path) | The path to mount the OIDC auth backend. | `string` | `"github-actions"` | no | |
| 364 | +| <a name="input_token_type"></a> [token\_type](#input\_token\_type) | The type of token to generate. This can be either `batch` or `service`. See <https://developer.hashicorp.com/vault/api-docs/auth/jwt#token_type> for more information. | `string` | `"batch"` | no | |
341 | 365 |
|
342 | 366 | ## Outputs |
343 | 367 |
|
|
0 commit comments