Skip to content

Commit 6ea7ed4

Browse files
authored
feat: add support for GHES (#39)
* feat: add support for GHES * chore: remove github-enterprise example until release is published with new variable
1 parent ea973a8 commit 6ea7ed4

File tree

15 files changed

+165
-19
lines changed

15 files changed

+165
-19
lines changed

.github/workflows/pr.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobs:
1515
- 'examples/simple-repo/'
1616
- 'examples/json-files/'
1717
- 'examples/additional-claims/'
18+
# - 'examples/github-enterprise/'
1819
- 'test/prepare-server/'
1920
- 'test/configure-vault/'
2021
- 'test/configure-oidc/'

README.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,24 @@
55
![GitHub contributors](https://img.shields.io/github/contributors/digitalocean/terraform-vault-github-oidc?style=flat-square)
66
![GitHub last commit](https://img.shields.io/github/last-commit/digitalocean/terraform-vault-github-oidc?style=flat-square)
77

8-
Terraform module to configure Vault for GitHub OIDC authentication from Action runners.
8+
Terraform module to configure Vault for GitHub OIDC authentication from Action runners on GitHub.com or self-hosted GitHub Enterprise Server.
99

1010
OIDC authentication allows us to bind GitHub repositories (and subcomponents of a repository, such as a branch, ref, or environment)
1111
to a Vault role without needing to manage actual credentials that require a lifecycle system, integration into repo-level
1212
GitHub Secrets, or other organizational glue.
1313

1414
Reference documents that help with understanding the process:
15-
- <https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault>
16-
- <https://medium.com/hashicorp-engineering/push-button-security-for-your-github-actions-d4fffde1df20>
15+
- <https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-hashicorp-vault>
1716

1817
Once OIDC authentication is configured on a Vault server via this module, a GitHub repository can leverage
1918
[hashicorp/vault-action](https://github.com/hashicorp/vault-action) to retrieve secrets from Vault with GitHub OIDC authentication.
2019
No credential management needed!
2120

21+
e.g.
22+
2223
```yml
2324
- name: Import Secrets
24-
uses: hashicorp/[email protected].0
25+
uses: hashicorp/[email protected].1
2526
id: secrets
2627
with:
2728
exportEnv: false
@@ -49,6 +50,7 @@ No credential management needed!
4950
- [oidc_bindings.ttl](#oidc_bindingsttl)
5051
- [default_ttl](#default_ttl)
5152
- [oidc_auth_backend_path](#oidc_auth_backend_path)
53+
- [github_identity_provider](#github_identity_provider)
5254
- [Requirements](#requirements)
5355
- [Providers](#providers)
5456
- [Modules](#modules)
@@ -65,7 +67,7 @@ The module requires you to configure what repositories to bind to Vault roles an
6567
conditions the respective repository should be granted access.
6668
This is encapsulated by the `oidc_bindings` variable.
6769

68-
| :exclamation: Note: This module uses the experimental Terraform feature [`module_variable_optional_attrs`](https://www.terraform.io/language/expressions/type-constraints#experimental-optional-object-type-attributes). |
70+
| :exclamation: Note: This module uses the experimental Terraform feature [`module_variable_optional_attrs`](https://www.terraform.io/language/expressions/type-constraints#experimental-optional-object-type-attributes) first introduced in v0.14. |
6971
|---|
7072

7173
You will need to opt-in to this experiment in your `terraform` block:
@@ -260,6 +262,18 @@ Do **not** include a leading `/` in the variable content.
260262
At this time, this module expects to create and manage the JWT backend leveraged for GitHub OIDC auth.
261263
You cannot pass in a Terraform reference to an existing backend.
262264

265+
### github_identity_provider
266+
267+
**Optional**
268+
269+
By default, this role will communicate with github.com for an OIDC JWT (`https://token.actions.githubusercontent.com`).
270+
If you run GitHub Enterprise Server, you will need to configure your instance of GitHub as the identity provider and should modify this variable.
271+
This requires GitHub Enterprise Server version 3.5 or higher.
272+
273+
The format is: `https://HOSTNAME/_services/token`.
274+
275+
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>.
276+
263277
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
264278
## Requirements
265279

@@ -292,6 +306,7 @@ No modules.
292306
| <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 |
293307
| <a name="input_default_ttl"></a> [default\_ttl](#input\_default\_ttl) | The default incremental time-to-live for generated tokens, in seconds. | `number` | `60` | no |
294308
| <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 |
309+
| <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 |
295310
| <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 |
296311

297312
## Outputs

examples/additional-claims/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ to an `oidc-binding` via this module.
2323

2424
| Name | Source | Version |
2525
|------|--------|---------|
26-
| <a name="module_github_oidc"></a> [github\_oidc](#module\_github\_oidc) | digitalocean/github-oidc/vault | ~> 1.0.1 |
26+
| <a name="module_github_oidc"></a> [github\_oidc](#module\_github\_oidc) | digitalocean/github-oidc/vault | ~> 1.0.2 |
2727

2828
## Resources
2929

examples/additional-claims/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ provider "vault" {
55

66
module "github_oidc" {
77
source = "digitalocean/github-oidc/vault"
8-
version = "~> 1.0.1"
8+
version = "~> 1.0.2"
99

1010
oidc_bindings = [
1111
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# GitHub Enterprise Server Example
2+
3+
Example configuration in this directory binds multiple Vault roles to one GitHub repository with GitHub OIDC.
4+
When using GitHub Enterprise Server, configure this module as normal and update the `github_identity_provider` variable [as applicable](https://github.com/digitalocean/terraform-vault-github-oidc#github_identity_provider) for your GitHub server.
5+
6+
# Usage
7+
8+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
9+
## Requirements
10+
11+
| Name | Version |
12+
|------|---------|
13+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.0 |
14+
| <a name="requirement_vault"></a> [vault](#requirement\_vault) | >= 3.4.1 |
15+
16+
## Providers
17+
18+
| Name | Version |
19+
|------|---------|
20+
| <a name="provider_vault"></a> [vault](#provider\_vault) | >= 3.4.1 |
21+
22+
## Modules
23+
24+
| Name | Source | Version |
25+
|------|--------|---------|
26+
| <a name="module_github_oidc"></a> [github\_oidc](#module\_github\_oidc) | digitalocean/github-oidc/vault | ~> 1.0.2 |
27+
28+
## Resources
29+
30+
| Name | Type |
31+
|------|------|
32+
| [vault_policy.example](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/resources/policy) | resource |
33+
| [vault_auth_backend.generated_backend](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/auth_backend) | data source |
34+
| [vault_policy_document.example](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/policy_document) | data source |
35+
36+
## Inputs
37+
38+
| Name | Description | Type | Default | Required |
39+
|------|-------------|------|---------|:--------:|
40+
| <a name="input_vault_address"></a> [vault\_address](#input\_vault\_address) | The origin URL of the Vault server. This is a URL with a scheme, a hostname, and a port but with no path. | `string` | n/a | yes |
41+
42+
## Outputs
43+
44+
| Name | Description |
45+
|------|-------------|
46+
| <a name="output_auth_backend_accessor"></a> [auth\_backend\_accessor](#output\_auth\_backend\_accessor) | The generated accessor ID for the auth backend. Outputting as demonstration of using a data source with the module. |
47+
| <a name="output_backend"></a> [backend](#output\_backend) | Exposing the auth backend path as an example. |
48+
| <a name="output_roles"></a> [roles](#output\_roles) | The list of Vault role names created by the module. This is a reflection of the `vault_role_name` value of each input item in `oidc-bindings`. |
49+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/github-enterprise/main.tf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Vault token should be provided in VAULT_TOKEN env var
2+
provider "vault" {
3+
address = var.vault_address
4+
}
5+
6+
module "github_oidc" {
7+
source = "digitalocean/github-oidc/vault"
8+
version = "~> 1.0.2"
9+
10+
github_identity_provider = "https://github.fakeexample.digitalocean.com/_services/token"
11+
12+
oidc_bindings = [
13+
{
14+
audience : "https://github.com/artis3n",
15+
vault_role_name : "oidc-test",
16+
bound_subject : "repo:artis3n/github-oidc-vault-example:environment:nonprod",
17+
vault_policies : [
18+
vault_policy.example.name,
19+
],
20+
},
21+
{
22+
audience : "https://github.com/artis3n",
23+
vault_role_name : "oidc-prod-test",
24+
bound_subject : "repo:artis3n/github-oidc-vault-example:ref:refs/heads/main",
25+
vault_policies : [
26+
vault_policy.example.name,
27+
],
28+
},
29+
]
30+
}
31+
32+
resource "vault_policy" "example" {
33+
name = "oidc-example"
34+
policy = data.vault_policy_document.example.hcl
35+
}
36+
37+
data "vault_policy_document" "example" {
38+
rule {
39+
path = "secret/data/foo/bar"
40+
capabilities = ["list", "read"]
41+
}
42+
}
43+
44+
data "vault_auth_backend" "generated_backend" {
45+
path = module.github_oidc.auth_backend_path
46+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "backend" {
2+
description = "Exposing the auth backend path as an example."
3+
value = module.github_oidc.auth_backend_path
4+
}
5+
6+
output "auth_backend_accessor" {
7+
description = "The generated accessor ID for the auth backend. Outputting as demonstration of using a data source with the module."
8+
value = data.vault_auth_backend.generated_backend.accessor
9+
}
10+
11+
output "roles" {
12+
description = "The list of Vault role names created by the module. This is a reflection of the `vault_role_name` value of each input item in `oidc-bindings`."
13+
value = module.github_oidc.oidc_bindings_names
14+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
variable "vault_address" {
2+
type = string
3+
description = "The origin URL of the Vault server. This is a URL with a scheme, a hostname, and a port but with no path."
4+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
terraform {
2+
required_version = ">= 1.1.0"
3+
experiments = [module_variable_optional_attrs]
4+
5+
required_providers {
6+
vault = {
7+
source = "hashicorp/vault"
8+
version = ">= 3.4.1"
9+
}
10+
}
11+
}

examples/json-files/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Dev teams create their own JSON files representing repos they own and wish to bi
3030

3131
| Name | Source | Version |
3232
|------|--------|---------|
33-
| <a name="module_github_oidc"></a> [github\_oidc](#module\_github\_oidc) | digitalocean/github-oidc/vault | ~> 1.0.1 |
33+
| <a name="module_github_oidc"></a> [github\_oidc](#module\_github\_oidc) | digitalocean/github-oidc/vault | ~> 1.0.2 |
3434

3535
## Resources
3636

0 commit comments

Comments
 (0)