Adding a HashiCorp Vault key Innovation Release

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.

  1. Set up the Helm repository:

    helm repo add hashicorp https://helm.releases.hashicorp.com
  2. Create 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
```
  1. Install Vault using the override:

    helm install -n vault vault hashicorp/vault --values helm-vault-raft-values.yml  --create-namespace
  2. 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:

  1. Access the pod where Vault is installed:

    kubectl -n vault exec --stdin=true --tty=true vault-0 -- /bin/sh
  2. Enable Kubernetes communication for the vault instance:

    vault auth enable kubernetes
  3. Update 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
  4. Enable the Transit secrets engine to activate key management capabilities:

    vault secrets enable transit
  5. Create 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
  6. Use the created file to update HashiCorp Vault's security policy:

    vault policy write tde /tmp/tde.txt
  7. Review 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.

  8. 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>
  9. Create a role called tde that 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 ttl value to specify how often an application will have to re-authenticate. See Vault's documentation on token metadata for more information.

  10. 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:

  1. 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.

  2. On the left-side navigation, select SettingsSecurity, and then + Add a key.

  3. Select a location to configure the key.

  4. Select HashiCorp Vault under Select key management system provider.

  5. In Vault Address, enter the HashiCorp Vault server endpoint.

    If Vault was installed in the vault namespace, and in the same Kubernetes environment as the Hybrid Manager, the default Kubernetes endpoint for Vault will be http://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>.

  6. In Vault Role, enter the name of the role you you created earlier, namely tde.

  7. In Vault Key, enter the name of the key you created earlier (<my-tde-key>).

  8. If desired, you can enter an alternative key name that is easy to remember in (Optional) Enter a friendly name for your key.

  9. 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.