Before you can create TDE-enabled clusters with a HashiCorp Vault key, an administrator must install and configure Vault for the Hybrid Manager instance.
Important
This walkthrough installs Vault inside the same Kubernetes cluster as Hybrid Manager and uses a wildcard policy (transit/*) and a wildcard service-account binding (p-*). This is a quickstart example to get you to a working TDE-enabled cluster quickly — it isn't a production reference architecture. Before using Vault-backed TDE in production, see Production hardening.
This example installs a customized version of Vault on the same Kubernetes environment as the Hybrid Manager, configures the Vault provider, and then uses the key to enable TDE for provisioning a new database cluster with encryption enabled.
If you're aiming for a vendor-neutral key management solution, it can be practical to use HashiCorp Vault, as it provides consistent, centralized key management across diverse cloud providers and on-premises environments, preventing vendor lock-in.
Prerequisites
hashicorp_vault is included in HM's default transparentDataEncryptionMethods list, so no HybridControlPlane change is needed to use it. If your installation has customized this list, confirm hashicorp_vault is still present. See Adding KMS support.
Installing Vault
Install HashiCorp Vault on the same Kubernetes environment where you have deployed the Hybrid Manager. Ensure you install it on its own vault namespace.
Set up the Helm repository:
helm repo add hashicorp https://helm.releases.hashicorp.comCreate a customization override for the installation to ensure Vault is installed on the Hybrid Manager's control plane, port 8200:
cat > helm-vault-raft-values.yml <<EOF injector: tolerations: | - key: "edbaiplatform.io/control-plane" effect: 'NoSchedule' operator: Equal value: "true"
affinity: |
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: 'edbaiplatform.io/control-plane'
operator: Exists
weight: 1
server:
tolerations: |
- key: "edbaiplatform.io/control-plane"
effect: 'NoSchedule'
operator: Equal
value: "true"
affinity: |
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: 'edbaiplatform.io/control-plane'
operator: Exists
weight: 1
ha:
enabled: true
raft:
enabled: true
setNodeId: true
config: |
cluster_name = "vault-integrated-storage"
storage "raft" {
path = "/vault/data/"
}
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8201"
tls_disable = "true"
}
service_registration "kubernetes" {}
EOF
```Install Vault using the override:
helm install -n vault vault hashicorp/vault --values helm-vault-raft-values.yml --create-namespace
Wait until all pods reach the "Healthy" status before proceeding:
kubectl -n vault get pods
Now you have to initialize your Vault instance using your base64-encoded public PGP key or Keybase username and unseal it with the master key. See Vault's documentation to Initialize and unseal Vault.
Configuring Vault and creating a key
Enable communication between the Vault service and the Hybrid Manager:
Access the pod where Vault is installed:
kubectl -n vault exec --stdin=true --tty=true vault-0 -- /bin/sh
Enable Kubernetes communication for the vault instance:
vault auth enable kubernetesUpdate Vault to authenticate with the Kubernetes cluster and allow the Hybrid Manager to use Vault:
vault write auth/kubernetes/config \ token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ kubernetes_host=https://${KUBERNETES_PORT_443_TCP_ADDR}:443 \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Enable the Transit secrets engine to activate key management capabilities:
vault secrets enable transitCreate a new file that contains the Vault policy definition for the keys:
In this example the file with the policy is called
tde.txt.cat > /tmp/tde.txt << EOL path "transit/*" { capabilities = ["create", "read", "update", "patch", "delete", "list"] } EOL
Use the created file to update HashiCorp Vault's security policy:
vault policy write tde /tmp/tde.txtReview the default parameter values for the Transit engine (e.g. around key rotation, encryption method, etc.) and adjust according to your requirements. Alternatively, can use the vault write command during key creation in the following step to override the default values for a specific key.
Create a new key that uses the transit engine:
Replace
<my-tde-key>with a key name of your choice.vault write -f transit/keys/<my-tde-key>
Create a role called
tdethat maps Vault policies to Kubernetes service accounts:vault write auth/kubernetes/role/tde \ bound_service_account_names="p-*" \ bound_service_account_namespaces="p-*" \ policies=tde \ ttl=72h
Note
You can configure a different
ttlvalue to specify how often an application will have to re-authenticate. See Vault's documentation on token metadata for more information.Exit the pod:
exit
Now that you have configured Vault and created a key, add it to a project in the PG AI Console.
Assigning the Vault key to a project
Add the created key to a project in Hybrid Manager using the console:
On the Console, go to the project under which you'll create TDE-enabled clusters. Each cluster is assigned to a specific key at creation time. You can register multiple keys in a project — see Deciding on a key-per-cluster or key-per-project strategy for guidance on choosing one key per project versus one key per cluster.
On the left-side navigation, select Settings ► Security, and then + Add a key.
Select a location to configure the key.
Select HashiCorp Vault under Select key management system provider.
In Vault Address, enter the HashiCorp Vault server endpoint.
If Vault was installed in the
vaultnamespace, and in the same Kubernetes environment as the Hybrid Manager, the default Kubernetes endpoint for Vault will behttp://vault.vault.svc.cluster.local:8200/. If your setup is different, infer the endpoint from your environment like this:<pod_name>.<namespace>.svc.cluster.<host>:<port_configured_for_vault>.In Vault Role, enter the name of the role you you created earlier, namely
tde.In Vault Key, enter the name of the key you created earlier (
<my-tde-key>).If desired, you can enter an alternative key name that is easy to remember in (Optional) Enter a friendly name for your key.
Select Add Key.
You can now use this key if you want to enable encryption when you create clusters. The added key will appear as an option when you enable TDE during cluster creation.
Production hardening
For production deployments, harden your Vault installation and configuration before relying on it for TDE-enabled clusters:
Topology
Run Vault outside the Hybrid Manager Kubernetes cluster, using an external Vault Enterprise deployment, HCP Vault, or a separately operated Vault cluster. Custody separation between the database administrator and the key custodian is the point of KMS-backed TDE; co-locating Vault with Hybrid Manager defeats it.
Least-privilege policy
Replace the transit/* wildcard policy with per-key paths scoped to the update capability only:
cat > /tmp/tde.txt << EOL path "transit/encrypt/<key-name>" { capabilities = ["update"] } path "transit/decrypt/<key-name>" { capabilities = ["update"] } EOL
Don't grant create, delete, or list on the transit engine to cluster service accounts — those capabilities let a compromised cluster identity create or destroy keys it shouldn't be able to touch.
Scoped role bindings
Replace the wildcard bound_service_account_namespaces="p-*" used when creating the tde role with the specific namespace of the cluster that key is meant to serve:
vault write auth/kubernetes/role/tde \ bound_service_account_names="<cluster-service-account>" \ bound_service_account_namespaces="<cluster-namespace>" \ policies=tde \ ttl=72h
A wildcard binding means every cluster in every namespace can reach every key, which defeats the per-cluster key isolation described in Deciding on a key-per-cluster or key-per-project strategy.