Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

Commit 43ed02f

Browse files
moo-im-a-cowDevelopmentCatsmatifalimafredri
authored
feat(vault-jwt): allow specifying the vault jwt token directly (#436)
Co-authored-by: Birdie K <5210502+moo-im-a-cow@users.noreply.github.com> Co-authored-by: DevCats <chris@dualriver.com> Co-authored-by: DevCats <christofer@coder.com> Co-authored-by: M Atif Ali <me@matifali.dev> Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
1 parent b14a03a commit 43ed02f

File tree

2 files changed

+119
-8
lines changed

2 files changed

+119
-8
lines changed

vault-jwt/README.md

Lines changed: 111 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@ tags: [helper, integration, vault, jwt, oidc]
1010

1111
# Hashicorp Vault Integration (JWT)
1212

13-
This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces by reusing the [OIDC](https://coder.com/docs/admin/users/oidc-auth) access token from Coder's OIDC authentication method. This requires configuring the Vault [JWT/OIDC](https://developer.hashicorp.com/vault/docs/auth/jwt#configuration) auth method.
13+
This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces by reusing the [OIDC](https://coder.com/docs/admin/users/oidc-auth) access token from Coder's OIDC authentication method or another source of jwt token. This requires configuring the Vault [JWT/OIDC](https://developer.hashicorp.com/vault/docs/auth/jwt#configuration) auth method.
1414

1515
```tf
1616
module "vault" {
17-
count = data.coder_workspace.me.start_count
18-
source = "registry.coder.com/modules/vault-jwt/coder"
19-
version = "1.0.31"
20-
agent_id = coder_agent.example.id
21-
vault_addr = "https://vault.example.com"
22-
vault_jwt_role = "coder" # The Vault role to use for authentication
17+
count = data.coder_workspace.me.start_count
18+
source = "registry.coder.com/modules/vault-jwt/coder"
19+
version = "1.1.0"
20+
agent_id = coder_agent.example.id
21+
vault_addr = "https://vault.example.com"
22+
vault_jwt_role = "coder" # The Vault role to use for authentication
23+
vault_jwt_token = "eyJhbGciOiJIUzI1N..." # optional, if not present, defaults to user's oidc authentication token
2324
}
2425
```
2526

@@ -79,3 +80,106 @@ module "vault" {
7980
vault_cli_version = "1.17.5"
8081
}
8182
```
83+
84+
### Use a custom JWT token
85+
86+
```tf
87+
88+
terraform {
89+
required_providers {
90+
jwt = {
91+
source = "geektheripper/jwt"
92+
version = "1.1.4"
93+
}
94+
time = {
95+
source = "hashicorp/time"
96+
version = "0.11.1"
97+
}
98+
}
99+
}
100+
101+
102+
resource "jwt_signed_token" "vault" {
103+
count = data.coder_workspace.me.start_count
104+
algorithm = "RS256"
105+
# `openssl genrsa -out key.pem 4096` and `openssl rsa -in key.pem -pubout > pub.pem` to generate keys
106+
key = file("key.pem")
107+
claims_json = jsonencode({
108+
iss = "https://code.example.com"
109+
sub = "${data.coder_workspace.me.id}"
110+
aud = "https://vault.example.com"
111+
iat = provider::time::rfc3339_parse(plantimestamp()).unix
112+
# Uncomment to set an expiry on the JWT token(default 3600 seconds).
113+
# workspace will need to be restarted to generate a new token if it expires
114+
#exp = provider::time::rfc3339_parse(timeadd(timestamp(), 3600)).unix agent = coder_agent.main.id
115+
provisioner = data.coder_provisioner.main.id
116+
provisioner_arch = data.coder_provisioner.main.arch
117+
provisioner_os = data.coder_provisioner.main.os
118+
119+
workspace = data.coder_workspace.me.id
120+
workspace_url = data.coder_workspace.me.access_url
121+
workspace_port = data.coder_workspace.me.access_port
122+
workspace_name = data.coder_workspace.me.name
123+
template = data.coder_workspace.me.template_id
124+
template_name = data.coder_workspace.me.template_name
125+
template_version = data.coder_workspace.me.template_version
126+
owner = data.coder_workspace_owner.me.id
127+
owner_name = data.coder_workspace_owner.me.name
128+
owner_email = data.coder_workspace_owner.me.email
129+
owner_login_type = data.coder_workspace_owner.me.login_type
130+
owner_groups = data.coder_workspace_owner.me.groups
131+
})
132+
}
133+
134+
module "vault" {
135+
count = data.coder_workspace.me.start_count
136+
source = "registry.coder.com/modules/vault-jwt/coder"
137+
version = "1.1.0"
138+
agent_id = coder_agent.example.id
139+
vault_addr = "https://vault.example.com"
140+
vault_jwt_role = "coder" # The Vault role to use for authentication
141+
vault_jwt_token = jwt_signed_token.vault[0].token
142+
}
143+
```
144+
145+
#### Example Vault JWT role
146+
147+
```shell
148+
vault write auth/JWT_MOUNT/role/workspace - << EOF
149+
{
150+
"user_claim": "sub",
151+
"bound_audiences": "https://vault.example.com",
152+
"role_type": "jwt",
153+
"ttl": "1h",
154+
"claim_mappings": {
155+
"owner": "owner",
156+
"owner_email": "owner_email",
157+
"owner_login_type": "owner_login_type",
158+
"owner_name": "owner_name",
159+
"provisioner": "provisioner",
160+
"provisioner_arch": "provisioner_arch",
161+
"provisioner_os": "provisioner_os",
162+
"sub": "sub",
163+
"template": "template",
164+
"template_name": "template_name",
165+
"template_version": "template_version",
166+
"workspace": "workspace",
167+
"workspace_name": "workspace_name",
168+
"workspace_id": "workspace_id"
169+
}
170+
}
171+
EOF
172+
```
173+
174+
#### Example workspace access Vault policy
175+
176+
```tf
177+
path "kv/data/app/coder/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.owner_name}}/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.workspace_name}}" {
178+
capabilities = ["create", "read", "update", "delete", "list", "subscribe"]
179+
subscribe_event_types = ["*"]
180+
}
181+
path "kv/metadata/app/coder/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.owner_name}}/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.workspace_name}}" {
182+
capabilities = ["create", "read", "update", "delete", "list", "subscribe"]
183+
subscribe_event_types = ["*"]
184+
}
185+
```

vault-jwt/main.tf

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ variable "vault_addr" {
2020
description = "The address of the Vault server."
2121
}
2222

23+
variable "vault_jwt_token" {
24+
type = string
25+
description = "The JWT token used for authentication with Vault."
26+
default = null
27+
sensitive = true
28+
}
29+
2330
variable "vault_jwt_auth_path" {
2431
type = string
2532
description = "The path to the Vault JWT auth method."
@@ -46,7 +53,7 @@ resource "coder_script" "vault" {
4653
display_name = "Vault (GitHub)"
4754
icon = "/icon/vault.svg"
4855
script = templatefile("${path.module}/run.sh", {
49-
CODER_OIDC_ACCESS_TOKEN : data.coder_workspace_owner.me.oidc_access_token,
56+
CODER_OIDC_ACCESS_TOKEN : var.vault_jwt_token != null ? var.vault_jwt_token : data.coder_workspace_owner.me.oidc_access_token,
5057
VAULT_JWT_AUTH_PATH : var.vault_jwt_auth_path,
5158
VAULT_JWT_ROLE : var.vault_jwt_role,
5259
VAULT_CLI_VERSION : var.vault_cli_version,

0 commit comments

Comments
 (0)