-
Notifications
You must be signed in to change notification settings - Fork 62
feat(vault-jwt): allow specifying the vault jwt token directly #436
Changes from 7 commits
fbf7312
e3bb4e7
c171d28
248c31c
407655b
28a70b0
41f875e
49d6765
65860cb
bd2fcf6
451f58e
898f140
4a3dab9
80dbe34
d9a6c49
3b9299f
1301bcb
6b2ae87
d6bcae5
e191d8f
51c46ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,16 +10,17 @@ tags: [helper, integration, vault, jwt, oidc] | |
|
|
||
| # Hashicorp Vault Integration (JWT) | ||
|
|
||
| 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. | ||
| 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. | ||
|
|
||
| ```tf | ||
| module "vault" { | ||
| count = data.coder_workspace.me.start_count | ||
| source = "registry.coder.com/modules/vault-jwt/coder" | ||
| version = "1.0.21" | ||
| agent_id = coder_agent.example.id | ||
| vault_addr = "https://vault.example.com" | ||
| vault_jwt_role = "coder" # The Vault role to use for authentication | ||
| count = data.coder_workspace.me.start_count | ||
| source = "registry.coder.com/modules/vault-jwt/coder" | ||
| version = "1.0.21" | ||
| agent_id = coder_agent.example.id | ||
| vault_addr = "https://vault.example.com" | ||
| vault_jwt_role = "coder" # The Vault role to use for authentication | ||
| vault_jwt_token = "eyJhbGciOiJIUzI1N..." # optional, if not present, defaults to user's oidc authentication token | ||
| } | ||
| ``` | ||
|
|
||
|
|
@@ -79,3 +80,105 @@ module "vault" { | |
| vault_cli_version = "1.17.5" | ||
| } | ||
| ``` | ||
|
|
||
| ### use a custom jwt token | ||
moo-im-a-cow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```tf | ||
|
|
||
| terraform { | ||
| required_providers { | ||
| jwt = { | ||
| source = "geektheripper/jwt" | ||
| version = "1.1.4" | ||
| } | ||
| time = { | ||
| source = "hashicorp/time" | ||
| version = "0.11.1" | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| resource "jwt_signed_token" "vault" { | ||
| count = data.coder_workspace.me.start_count | ||
| algorithm = "RS256" | ||
| # `openssl genrsa -out key.pem 4096` and `openssl rsa -in key.pem -pubout > pub.pem` to generate keys | ||
| key = file("key.pem") | ||
| claims_json = jsonencode({ | ||
| iss = "https://code.example.com" | ||
| sub = "${data.coder_workspace.me.id}" | ||
| aud = "https://vault.example.com" | ||
| iat = provider::time::rfc3339_parse(plantimestamp()).unix | ||
| # exp = timeadd(timestamp(), 3600) | ||
|
||
| agent = coder_agent.main.id | ||
| provisioner = data.coder_provisioner.main.id | ||
| provisioner_arch = data.coder_provisioner.main.arch | ||
| provisioner_os = data.coder_provisioner.main.os | ||
|
|
||
| workspace = data.coder_workspace.me.id | ||
| workspace_url = data.coder_workspace.me.access_url | ||
| workspace_port = data.coder_workspace.me.access_port | ||
| workspace_name = data.coder_workspace.me.name | ||
| template = data.coder_workspace.me.template_id | ||
| template_name = data.coder_workspace.me.template_name | ||
| template_version = data.coder_workspace.me.template_version | ||
| owner = data.coder_workspace_owner.me.id | ||
| owner_name = data.coder_workspace_owner.me.name | ||
| owner_email = data.coder_workspace_owner.me.email | ||
| owner_login_type = data.coder_workspace_owner.me.login_type | ||
| owner_groups = data.coder_workspace_owner.me.groups | ||
| }) | ||
| } | ||
|
|
||
| module "vault" { | ||
| count = data.coder_workspace.me.start_count | ||
| source = "registry.coder.com/modules/vault-jwt/coder" | ||
| version = "1.0.20" | ||
moo-im-a-cow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| agent_id = coder_agent.example.id | ||
| vault_addr = "https://vault.example.com" | ||
| vault_jwt_role = "coder" # The Vault role to use for authentication | ||
| vault_jwt_token = jwt_signed_token.vault[0].token | ||
| } | ||
| ``` | ||
|
|
||
| #### example vault jwt role | ||
moo-im-a-cow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ``` | ||
moo-im-a-cow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| vault write auth/<JWT_MOUNT>/role/workspace -<<EOF | ||
| { | ||
| "user_claim": "sub", | ||
| "bound_audiences": "https://vault.example.com", | ||
| "role_type": "jwt", | ||
| "ttl": "1h", | ||
| "claim_mappings": { | ||
| "owner": "owner", | ||
| "owner_email": "owner_email", | ||
| "owner_login_type": "owner_login_type", | ||
| "owner_name": "owner_name", | ||
| "provisioner": "provisioner", | ||
| "provisioner_arch": "provisioner_arch", | ||
| "provisioner_os": "provisioner_os", | ||
| "sub": "sub", | ||
| "template": "template", | ||
| "template_name": "template_name", | ||
| "template_version": "template_version", | ||
| "workspace": "workspace", | ||
| "workspace_name": "workspace_name", | ||
| "workspace_id": "workspace_id" | ||
| } | ||
moo-im-a-cow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| EOF | ||
| ``` | ||
|
|
||
| #### example workspace access vault policy | ||
moo-im-a-cow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```hcl | ||
| path "kv/data/app/coder/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.owner_name}}/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.workspace_name}}" { | ||
| capabilities = ["create", "read", "update", "delete", "list", "subscribe"] | ||
| subscribe_event_types = ["*"] | ||
| } | ||
| path "kv/metadata/app/coder/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.owner_name}}/{{identity.entity.aliases.<MOUNT_ACCESSOR>.metadata.workspace_name}}" { | ||
| capabilities = ["create", "read", "update", "delete", "list", "subscribe"] | ||
| subscribe_event_types = ["*"] | ||
| } | ||
| ``` | ||
Uh oh!
There was an error while loading. Please reload this page.