本文为 SPIRE 官方文档 plugin_server_keymanager_hashicorp_vault 的中文译本,以英文原文为准。
🔗 穿越源码分析:Server 详解 · KeyManager
服务端插件:KeyManager "hashicorp_vault"
hashicorp_vault 密钥管理器(key manager)插件借助 HashiCorp Vault 来创建、维护并轮换密钥对,并按需签发 SVID。
配置
该插件接受以下配置项:
| 键名 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| key_identifier_file | string | 若未设置 key_identifier_value 则必填 | 一个文件路径,用于持久化所生成密钥的相关信息。更多信息见"密钥的管理"。 | "" |
| key_identifier_value | string | 若未设置 key_identifier_file 则必填 | SPIRE server 实例的静态标识符(用于替代 key_identifier_file)。 | "" |
| vault_addr | string | Vault 服务器的 URL。(例如 https://vault.example.com:8443/) | ${VAULT_ADDR} | |
| namespace | string | Vault 命名空间(namespace)的名称。仅在 Vault Enterprise 中可用。 | ${VAULT_NAMESPACE} | |
| transit_engine_path | string | 存储密钥的 transit 引擎(transit engine)的路径。 | transit | |
| ca_cert_path | string | 用于校验 Vault 服务器证书的 CA 证书文件路径。仅支持 PEM 格式。 | ${VAULT_CACERT} | |
| insecure_skip_verify | bool | 若为 true,vault 客户端将接受任意服务器证书。只应在测试环境中使用。 | false | |
| cert_auth | struct | 客户端证书(Client Certificate)认证方式的配置 | ||
| token_auth | struct | 令牌(Token)认证方式的配置 | ||
| approle_auth | struct | AppRole 认证方式的配置 | ||
| k8s_auth | struct | Kubernetes 认证方式的配置 |
环境变量
插件会读取以下环境变量。标注为"标准"的变量会被 Vault CLI 与客户端库原生识别——完整参考见 Vault 文档。
| 变量 | 标准 | 说明 |
|---|---|---|
VAULT_ADDR | 是 | Vault 服务器的地址 |
VAULT_CACERT | 是 | CA 证书文件的路径 |
VAULT_CLIENT_CERT | 是 | 客户端证书文件的路径(cert 认证) |
VAULT_CLIENT_KEY | 是 | 客户端私钥文件的路径(cert 认证) |
VAULT_NAMESPACE | 是 | Vault 命名空间(仅 Enterprise) |
VAULT_TOKEN | 是 | Vault 令牌(token 认证) |
VAULT_APPROLE_ID | 否 | AppRole 的 role ID —— SPIRE 专用,并非 Vault SDK 变量 |
VAULT_APPROLE_SECRET_ID | 否 | AppRole 的 secret ID —— SPIRE 专用,并非 Vault SDK 变量 |
VAULT_TRANSIT_ENGINE_PATH | 否 | transit 引擎路径 —— SPIRE 专用,回退默认值为 transit |
插件支持 客户端证书(Client Certificate)、令牌(Token)、AppRole 和 Kubernetes 四种认证方式。
- 客户端证书(Client Certificate) 方式使用 TLS 客户端证书向 Vault 认证。
- 令牌(Token) 方式使用 HTTP 请求头中的令牌向 Vault 认证。
- AppRole 方式使用由 Vault 签发的 RoleID 与 SecretID 向 Vault 认证。
- Kubernetes 方式使用 Kubernetes 服务账号令牌(Service Account Token)向 Vault 认证。
所配置的令牌需要绑定到一个至少具备以下能力(capabilities)的策略(policy)上:
path "transit/keys/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "transit/sign/*" {
capabilities = ["update"]
}客户端证书认证(Client Certificate Authentication)
| 键名 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| cert_auth_mount_point | string | TLS 证书认证方式挂载点(mount point)的名称 | cert | |
| cert_auth_role_name | string | Vault 角色(role)的名称。若给定,插件仅针对该命名角色进行认证。默认尝试所有角色。 | ||
| client_cert_path | string | 客户端证书文件的路径。仅支持 PEM 格式。 | ${VAULT_CLIENT_CERT} | |
| client_key_path | string | 客户端私钥文件的路径。仅支持 PEM 格式。 | ${VAULT_CLIENT_KEY} |
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
ca_cert_path = "/path/to/ca-cert.pem"
cert_auth {
cert_auth_mount_point = "test-tls-cert-auth"
client_cert_path = "/path/to/client-cert.pem"
client_key_path = "/path/to/client-key.pem"
}
// 若要指定用于认证的角色
// cert_auth {
// cert_auth_mount_point = "test-tls-cert-auth"
// cert_auth_role_name = "test"
// client_cert_path = "/path/to/client-cert.pem"
// client_key_path = "/path/to/client-key.pem"
// }
// 若通过环境变量指定密钥对,并使用修改后的挂载点
// cert_auth {
// cert_auth_mount_point = "test-tls-cert-auth"
// }
// 若通过环境变量指定密钥对,并使用默认挂载点,则设为空结构体。
// cert_auth {}
}
}令牌认证(Token Authentication)
| 键名 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| token | string | 要设置到 "X-Vault-Token" 请求头中的令牌字符串 | ${VAULT_TOKEN} |
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
ca_cert_path = "/path/to/ca-cert.pem"
token_auth {
token = "<token>"
}
// 若通过环境变量指定令牌,则设为空结构体。
// token_auth {}
}
}AppRole 认证(AppRole Authentication)
| 键名 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| approle_auth_mount_point | string | AppRole 认证方式挂载点(mount point)的名称 | approle | |
| approle_id | string | AppRole 的标识符 | ${VAULT_APPROLE_ID} | |
| approle_secret_id | string | AppRole 的凭据 | ${VAULT_APPROLE_SECRET_ID} |
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
ca_cert_path = "/path/to/ca-cert.pem"
approle_auth {
approle_auth_mount_point = "my-approle-auth"
approle_id = "<Role ID>" // 或通过环境变量指定
approle_secret_id = "<Secret ID>" // 或通过环境变量指定
}
// 若通过环境变量指定 approle_id 和 approle_secret,并使用修改后的挂载点
// approle_auth {
// approle_auth_mount_point = "my-approle-auth"
// }
// 若通过环境变量指定 approle_id 和 approle_secret,并使用默认挂载点,则设为空结构体。
// approle_auth {}
}
}Kubernetes 认证(Kubernetes Authentication)
| 键名 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| k8s_auth_mount_point | string | Kubernetes 认证方式挂载点(mount point)的名称 | kubernetes | |
| k8s_auth_role_name | string | ✔ | Vault 角色(role)的名称。插件针对该命名角色进行认证 | |
| token_path | string | ✔ | 用于向 Vault 认证的 Kubernetes 服务账号令牌(Service Account Token)的路径 |
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
ca_cert_path = "/path/to/ca-cert.pem"
k8s_auth {
k8s_auth_mount_point = "my-k8s-auth"
k8s_auth_role_name = "my-role"
token_path = "/path/to/sa-token"
}
// 若指定角色名,并使用默认挂载点与 token_path
// k8s_auth {
// k8s_auth_role_name = "my-role"
// }
}
}密钥的管理
插件需要一种方式来识别它正在其上运行的具体 server 实例。为此,必须使用 key_identifier_file 或 key_identifier_value 两者之一。设置**密钥标识文件(Key Identifier File)**会指示插件自动管理 server 的标识符,将 server ID 存储在指定 文件中。这种方式适用于大多数情况。如果配置了_密钥标识文件_而在 server 启动时未 找到该文件,则会以新的、自动生成的 server ID 重新创建该文件。因此,如果该文件丢 失,插件将无法识别它此前管理过的密钥,并会按需重新创建新密钥。
如果你需要对 server 所用的标识符有更多控制,可以使用 key_identifier_value 设置 来为 server 实例指定一个静态标识符。这种设置适用于无法持久化密钥标识文件的场景。