Contents
KMS: HashiCorp Vault / OpenBao
Selected with pg_vault_tde.kms_provider = 'vault' (there is no default
provider — see Key Management Overview). The KEK
is held and used entirely inside Vault’s/OpenBao’s Transit secrets
engine — pg_vault_tde only ever sees wrapped DEKs; the raw KEK material
never leaves Vault.
When to Use It
Centralized key management across multiple PostgreSQL clusters, existing Vault/OpenBao infrastructure, environments where key custody and audit trail need to live in a dedicated secrets-management system rather than on the database host.
Vault-Side Setup
Enable the Transit engine and create a policy that only allows wrap/unwrap (encrypt/decrypt) operations — pg_vault_tde never needs to read the key material itself:
path "transit/decrypt/pg-tde-dek" {
capabilities = ["update"]
}
path "transit/encrypt/pg-tde-dek" {
capabilities = ["update"]
}
PostgreSQL-Side Configuration
pg_vault_tde.kms_provider = 'vault'
pg_vault_tde.vault_url = 'https://vault.example.com:8200'
pg_vault_tde.vault_namespace = '' # leave empty for Vault Community Edition
pg_vault_tde.vault_token = 'hvs.TOKEN' # or use AppRole / Kubernetes auth, below
pg_vault_tde.vault_transit_mount = 'transit'
pg_vault_tde.vault_key_name = 'pg-tde-dek'
pg_vault_tde.vault_ca_cert = '/etc/ssl/vault/ca.pem'
pg_vault_tde.vault_timeout_ms = 5000
pg_vault_tde.enabled = on
All of these are suset — changeable per-database with ALTER DATABASE ...
SET, with no restart required (enabled is the one exception — see the
warning in Encrypted Tables and Indexes and
GUC Reference).
vault_token, vault_secret_id, and the wallet passphrase GUCs are hidden
from pg_settings (only visible to a superuser) so they don’t leak through
SHOW ALL or monitoring queries that read the catalog.
Authentication Methods
Set vault_auth_method to select how PostgreSQL authenticates to Vault:
| Method | Relevant GUCs |
|---|---|
token (default) |
vault_token |
approle |
vault_role_id, vault_secret_id, vault_role_name (enables automatic secret_id rotation after login) |
kubernetes |
vault_k8s_role, vault_k8s_mount |
Background Token Renewal
A background worker can renew the active Vault token lease automatically:
pg_vault_tde.bgw_enabled = on
pg_vault_tde.token_renewal_interval = 3600 # seconds, 60–86400
bgw_enabled requires a cluster restart to take effect — the worker is
registered via RegisterBackgroundWorker() at postmaster startup, so
pg_reload_conf() alone does not start or stop it. You can also renew a
token manually:
SELECT pg_vault_tde_refresh_token();
Checking Vault Connectivity
SELECT * FROM pg_vault_tde_vault_status(); -- (configured, auth_method, reachable)
SELECT * FROM pg_vault_tde_health_check();
Rotation
- DEK rotation (per table) and KEK rotation (
pg_vault_tde_rotate_kek(), which asks Vault Transit to rewrap every stored DEK under a new Transit key version) both work with this provider — see Key Rotation. - Vault’s own Transit key versioning means old key versions remain available for rewrap, so KEK rotation does not require re-encrypting any table data.
Migrating to the Local Wallet
If you need to move a database off Vault (e.g. decommissioning a Vault cluster, or moving a tenant to a fully offline deployment):
SELECT pg_vault_tde_migrate_vault_to_wallet('a-new-wallet-passphrase');
This is an online migration — see KMS: Local Wallet for wallet setup details first.