feat: Add support for Vault namespaces to Vault modules (#554)

## Description

Adds support for accessing auth mounts/secret engines located in a non
root namespace. Namespaces is a feature of Vault Enterprise.

## Type of Change

- [ ] New module
- [ ] New template
- [ ] Bug fix
- [x] Feature/enhancement
- [ ] Documentation
- [ ] Other

## Module Information

**Path:** `registry/coder/modules/vault-github`  
**New version:** `v1.1.0`  
**Breaking change:** [ ] Yes [x] No

**Path:** `registry/coder/modules/vault-jwt`  
**New version:** `v1.2.0`  
**Breaking change:** [ ] Yes [x] No

**Path:** `registry/coder/modules/vault-token`  
**New version:** `v1.3.0`  
**Breaking change:** [ ] Yes [x] No

## Testing & Validation

- [x] Tests pass (`bun test`)
- [x] Code formatted (`bun fmt`)
- [x] Changes tested locally

## Related Issues

None

---------

Co-authored-by: DevCats <christofer@coder.com>
This commit is contained in:
Rowan Smith 2025-11-21 03:48:13 +11:00 committed by GitHub
parent b4c162d281
commit 5f3a559e83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 59 additions and 12 deletions

View File

@ -14,7 +14,7 @@ This module lets you authenticate with [Hashicorp Vault](https://www.vaultprojec
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-github/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
}
@ -46,7 +46,7 @@ To configure the Vault module, you must set up a Vault GitHub auth method. See t
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-github/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
coder_github_auth_id = "my-github-auth-id"
@ -59,7 +59,7 @@ module "vault" {
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-github/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
coder_github_auth_id = "my-github-auth-id"
@ -73,7 +73,7 @@ module "vault" {
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-github/coder"
version = "1.0.31"
version = "1.1.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_cli_version = "1.15.0"

View File

@ -32,6 +32,12 @@ variable "vault_github_auth_path" {
default = "github"
}
variable "vault_namespace" {
type = string
description = "The Vault Enterprise namespace that contains the GitHub auth mount."
default = null
}
variable "vault_cli_version" {
type = string
description = "The version of Vault to install."
@ -52,6 +58,7 @@ resource "coder_script" "vault" {
AUTH_PATH : var.vault_github_auth_path,
GITHUB_EXTERNAL_AUTH_ID : data.coder_external_auth.github.id,
INSTALL_VERSION : var.vault_cli_version,
VAULT_NAMESPACE : var.vault_namespace != null ? var.vault_namespace : "",
})
run_on_start = true
start_blocks_login = true
@ -63,6 +70,13 @@ resource "coder_env" "vault_addr" {
value = var.vault_addr
}
resource "coder_env" "vault_namespace" {
count = var.vault_namespace == null ? 0 : 1
agent_id = var.agent_id
name = "VAULT_NAMESPACE"
value = var.vault_namespace
}
data "coder_external_auth" "github" {
id = var.coder_github_auth_id
}

View File

@ -4,6 +4,7 @@
INSTALL_VERSION=${INSTALL_VERSION}
GITHUB_EXTERNAL_AUTH_ID=${GITHUB_EXTERNAL_AUTH_ID}
AUTH_PATH=${AUTH_PATH}
VAULT_NAMESPACE=${VAULT_NAMESPACE}
fetch() {
dest="$1"
@ -104,6 +105,11 @@ if ! (
fi
rm -rf "$TMP"
if [ -n "$${VAULT_NAMESPACE}" ]; then
export VAULT_NAMESPACE
printf "📁 Using Vault namespace: %s\n\n" "$${VAULT_NAMESPACE}"
fi
# Authenticate with Vault
printf "🔑 Authenticating with Vault ...\n\n"
GITHUB_TOKEN=$(coder external-auth access-token "$${GITHUB_EXTERNAL_AUTH_ID}")

View File

@ -14,7 +14,7 @@ This module lets you authenticate with [Hashicorp Vault](https://www.vaultprojec
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-jwt/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_jwt_role = "coder" # The Vault role to use for authentication
@ -42,7 +42,7 @@ curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/coder/secrets/d
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-jwt/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_jwt_auth_path = "oidc"
@ -58,7 +58,7 @@ data "coder_workspace_owner" "me" {}
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-jwt/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_jwt_role = data.coder_workspace_owner.me.groups[0]
@ -71,7 +71,7 @@ module "vault" {
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-jwt/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_jwt_role = "coder" # The Vault role to use for authentication
@ -132,7 +132,7 @@ resource "jwt_signed_token" "vault" {
module "vault" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/vault-jwt/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_jwt_role = "coder" # The Vault role to use for authentication

View File

@ -38,6 +38,12 @@ variable "vault_jwt_role" {
description = "The name of the Vault role to use for authentication."
}
variable "vault_namespace" {
type = string
description = "The Vault Enterprise namespace that contains the JWT auth mount."
default = null
}
variable "vault_cli_version" {
type = string
description = "The version of Vault to install."
@ -57,6 +63,7 @@ resource "coder_script" "vault" {
VAULT_JWT_AUTH_PATH : var.vault_jwt_auth_path,
VAULT_JWT_ROLE : var.vault_jwt_role,
VAULT_CLI_VERSION : var.vault_cli_version,
VAULT_NAMESPACE : var.vault_namespace != null ? var.vault_namespace : "",
})
run_on_start = true
start_blocks_login = true
@ -68,4 +75,11 @@ resource "coder_env" "vault_addr" {
value = var.vault_addr
}
resource "coder_env" "vault_namespace" {
count = var.vault_namespace == null ? 0 : 1
agent_id = var.agent_id
name = "VAULT_NAMESPACE"
value = var.vault_namespace
}
data "coder_workspace_owner" "me" {}

View File

@ -4,6 +4,7 @@
VAULT_CLI_VERSION=${VAULT_CLI_VERSION}
VAULT_JWT_AUTH_PATH=${VAULT_JWT_AUTH_PATH}
VAULT_JWT_ROLE=${VAULT_JWT_ROLE}
VAULT_NAMESPACE=${VAULT_NAMESPACE}
CODER_OIDC_ACCESS_TOKEN=${CODER_OIDC_ACCESS_TOKEN}
fetch() {
@ -105,6 +106,11 @@ if ! (
fi
rm -rf "$TMP"
if [ -n "$${VAULT_NAMESPACE}" ]; then
export VAULT_NAMESPACE
printf "📁 Using Vault namespace: %s\n\n" "$${VAULT_NAMESPACE}"
fi
# Authenticate with Vault
printf "🔑 Authenticating with Vault ...\n\n"
echo "$${CODER_OIDC_ACCESS_TOKEN}" | vault write -field=token auth/"$${VAULT_JWT_AUTH_PATH}"/login role="$${VAULT_JWT_ROLE}" jwt=- | vault login -

View File

@ -19,7 +19,7 @@ variable "vault_token" {
module "vault" {
source = "registry.coder.com/coder/vault-token/coder"
version = "1.2.2"
version = "1.3.0"
agent_id = coder_agent.example.id
vault_token = var.token # optional
vault_addr = "https://vault.example.com"
@ -73,7 +73,7 @@ variable "vault_token" {
module "vault" {
source = "registry.coder.com/coder/vault-token/coder"
version = "1.2.2"
version = "1.3.0"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_token = var.token

View File

@ -50,6 +50,7 @@ resource "coder_script" "vault" {
icon = "/icon/vault.svg"
script = templatefile("${path.module}/run.sh", {
INSTALL_VERSION : var.vault_cli_version,
VAULT_NAMESPACE : var.vault_namespace != null ? var.vault_namespace : "",
})
run_on_start = true
start_blocks_login = true
@ -73,4 +74,4 @@ resource "coder_env" "vault_namespace" {
agent_id = var.agent_id
name = "VAULT_NAMESPACE"
value = var.vault_namespace
}
}

View File

@ -2,6 +2,7 @@
# Convert all templated variables to shell variables
INSTALL_VERSION=${INSTALL_VERSION}
VAULT_NAMESPACE=${VAULT_NAMESPACE}
fetch() {
dest="$1"
@ -101,3 +102,8 @@ if ! (
exit 1
fi
rm -rf "$TMP"
if [ -n "$${VAULT_NAMESPACE}" ]; then
export VAULT_NAMESPACE
printf "📁 Using Vault namespace: %s\n\n" "$${VAULT_NAMESPACE}"
fi