-
Notifications
You must be signed in to change notification settings - Fork 58
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.
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should either be removed or have an associated comment (uncomment to ...). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you mean just the exp field? or the sub, aud, iat, exp fields? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assuming you only meant the exp field, i've fixed it up and added a comment describing it and the pro/con of uncommenting it (making the token expire) |
||
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.
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.
Show resolved
Hide resolved
|
||
|
||
``` | ||
moo-im-a-cow marked this conversation as resolved.
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.
Show resolved
Hide resolved
|
||
} | ||
EOF | ||
``` | ||
|
||
#### example workspace access vault policy | ||
moo-im-a-cow marked this conversation as resolved.
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.