Vault KV engines, paths, and policies¶
This library reads secrets from HashiCorp Vault KV secrets engines. KV v1 and KV v2 use different HTTP paths and response shapes. pydantic2-settings-vault normalizes logical paths and parses responses based on the configured KV version.
KV version configuration¶
Set the default KV version with VAULT_KV_VERSION:
| Value | Engine | Default |
|---|---|---|
2 |
KV secrets engine v2 | yes |
1 |
KV secrets engine v1 |
Override per field with vault_kv_version in json_schema_extra:
DB_PASSWORD: SecretStr = Field(
...,
json_schema_extra={
"vault_secret_path": "legacy/data/app",
"vault_secret_key": "password",
"vault_kv_version": 1,
},
)
validate_vault_configuration reports invalid global or per-field KV version values before settings load.
Path conventions¶
KV v2 (default)¶
Logical path (recommended in field metadata):
HTTP API path used by Vault:
You can still use the full API path (secret/data/myapp/config) in vault_secret_path; the library leaves it unchanged.
KV v1¶
Logical path:
HTTP API path:
If a v1 field accidentally uses a v2-style path (secretv1/data/myapp/config), the library strips the data/ segment before the HTTP request.
Field-mapping patterns¶
Group secrets by Vault path¶
Map several settings fields to the same vault_secret_path and different vault_secret_key values. The source fetches each unique path once and shares the result across fields.
class AppSettings(BaseSettings):
DB_HOST: str = Field(
...,
json_schema_extra={
"vault_secret_path": "secret/myapp/database",
"vault_secret_key": "host",
},
)
DB_PASSWORD: SecretStr = Field(
...,
json_schema_extra={
"vault_secret_path": "secret/myapp/database",
"vault_secret_key": "password",
},
)
Namespace paths by application and environment¶
Use mount and path segments that match your Vault layout, for example secret/prod/myapp/database or secret/staging/myapp/database. Keep production and non-production paths distinct so policies can scope access per environment.
One secret per sensitive value¶
For high-sensitivity values with different rotation or access requirements, use separate Vault paths and map each field to its own path. This increases HTTP requests but simplifies least-privilege policies.
Recommended Vault policies¶
Grant read access only to the paths your application needs. Examples assume AppRole auth at mount approle; adjust auth paths and roles to match your deployment.
KV v2 read policy¶
path "secret/data/myapp/*" {
capabilities = ["read"]
}
path "auth/approle/login" {
capabilities = ["create", "update"]
}
KV v1 read policy¶
path "secretv1/myapp/*" {
capabilities = ["read"]
}
path "auth/approle/login" {
capabilities = ["create", "update"]
}
Mixed engines¶
When one service reads both v1 and v2 mounts, combine path rules:
path "secret/data/myapp/*" {
capabilities = ["read"]
}
path "legacy/myapp/*" {
capabilities = ["read"]
}
Enterprise namespaces¶
When using VAULT_NAMESPACE, policies are defined inside that namespace. The library sends X-Vault-Namespace on authentication and secret reads; policy paths refer to secrets within that namespace.
Environment variables summary¶
| Variable | Purpose |
|---|---|
VAULT_KV_VERSION |
Default KV engine version (1 or 2, default 2) |
VAULT_URL |
Vault API base URL |
VAULT_NAMESPACE |
Optional Enterprise namespace |
VAULT_AUTH_METHOD |
Authentication method (default approle) |
See Authentication for auth configuration. See the Usage guide for end-to-end setup and field annotation patterns.