Before you begin
Configure HashiCorp Vault's KV-V2 secrets engine to make sure that the Key Encryption Key (KEK) path and JSON Web Token (JWT) are available.
Verify that AlloyDB Omni has permission to read the JWT token file.
Create the cluster
To create a TDE-enabled cluster, you must pass the necessary Key Management
Service (KMS) configuration and authentication credentials during the
initialization of the database. The only supported authentication type is jwt.
Install AlloyDB Omni using RPM to prepare your environment and install the AlloyDB Omni RPM package.
Initialize the database.
HashiCorp Vault KMS
Use this approach for production workloads.
Run the following command to initialize the database with TDE enabled:
sudo PGPASSWORD=POSTGRES_PASSWORD \ PGDATA=DATA_DIR \ VAULT_AUTH_TYPE=jwt \ VAULT_AUTH_MOUNT=JWT_AUTH_ENGINE_MOUNT \ VAULT_JWT_PATH=JWT_FILE_PATH \ VAULT_ROLE=VAULT_ROLE \ VAULT_CERT_PATH=VAULT_CERT_PATH \ POSTGRES_INITDB_ARGS="--tde-kek-url=KEK_URL" \ /usr/lib/postgresql/18/bin/alloydbomni18-setup initdb
Replace the following:
POSTGRES_PASSWORD: the password for the database user.DATA_DIR: the local directory to mount as the data volume for AlloyDB Omni—for example,/local/data.VAULT_AUTH_TYPE: the type of authentication to use for the vault connection. Onlyjwtis supported.JWT_AUTH_ENGINE_MOUNT: the path where the HashiCorp Vault authentication engine is mounted—for example,/auth/jwt.JWT_FILE_PATH: the path where vault JWT is stored on your nodes—for example,tde-tls/jwt-token.- (Optional)
VAULT_ROLE: the client role defined in your vault setup that lets HashiCorp Vault verify the JWT token authenticity. VAULT_CERT_PATH: the path where the certificates for the vault connection are located in your container—for example,/tde-tls. If not set, the certificates in the default trust store are used.KEK_URL: the fully qualified URL to the KEK in HashiCorp Vault. Usevaultas the protocol to specify HashiCorp Vault as the KMS provider—for example,vault://127.0.0.1:8200/v1/secrets/data/alloydb_kek.
To create an override file for
alloydbomni.service in /etc/systemd/system/alloydbomni18.service.d/override.conf, add the following to theoverride.conffile:[Service] Environment="VAULT_AUTH_TYPE" Environment="VAULT_AUTH_MOUNT=JWT_AUTH_ENGINE_MOUNT" Environment="VAULT_JWT_PATH=JWT_FILE_PATH" Environment="VAULT_ROLE=VAULT_ROLE" Environment="VAULT_CERT_PATH=VAULT_CERT_PATH"
To apply the changes, reload the systemd daemon.
sudo systemctl daemon-reload
File Based KMS
Use this approach for testing purposes only.
To test TDE locally using a file-based key, you must first generate a 32 byte KEK on your machine.
Create the directory, generate the key, and set the appropriate permissions.
KEK_DIR=KEK_DIR mkdir -p $KEK_DIR sudo chown 999:999 $KEK_DIR openssl rand -base64 32 | sudo tee $KEK_DIR/key sudo chmod 0755 $KEK_DIR/key
Initialize the database by passing the local file URI as your KEK URL.
sudo PGPASSWORD=POSTGRES_PASSWORD \ PGDATA=DATA_DIR \ POSTGRES_INITDB_ARGS="--tde-kek-url=file:///$KEK_DIR/key" \ /usr/lib/postgresql/18/bin/alloydbomni18-setup initdb
Replace the following:
POSTGRES_PASSWORD: the password for the database user.DATA_DIR: the local directory to mount as the data volume for AlloyDB Omni—for example,/local/data.KEK_DIR: the directory where the local file-based KEK is stored—for example,/tmp/alloydb/kms.
After the database is initialized, follow the instructions in Install AlloyDB Omni using RPM to prepare the database, set up the host, and start the
systemdservice.
View TDE metrics
After the cluster is initialized, complete the following steps to verify that TDE is enabled and view related TDE metrics.
- Connect to your database using
psqlor your preferred client. For detailed instructions on connecting to your instances, see Run and connect to AlloyDB Omni. Run the following command:
select * FROM pgsnap.g$tde_stats;The output shows TDE metrics such as whether TDE is enabled, the KEK URL, KEK version, and KEK creation timestamp.
The following table explains what each metric means.
Name Description Label Unit Type alloydb_omni_database_tde_data_blocks_decrypted_count_totalNumber of data blocks decrypted. Not applicable counter alloydb_omni_database_tde_data_blocks_encrypted_count_totalNumber of data blocks encrypted. Not applicable counter alloydb_omni_database_tde_data_decryption_time_us_totalTotal time spent in data block decryption. Not applicable microseconds counter alloydb_omni_database_tde_data_encryption_time_us_totalTotal time spent in data block encryption. Not applicable microseconds counter alloydb_omni_database_tde_enabledTDE enabled status. Not applicable gauge alloydb_omni_database_tde_kek_infoTDE KEK information. kek_version: Version of the KEK
in use for key wrapping.kek_url: Fully qualified path
to KEK in KMSkek_creation_timestamp:
Creation time of the KEK version in use.
gauge alloydb_omni_database_tde_temp_blocks_decrypted_count_totalNumber of temporary blocks decrypted. Not applicable counter alloydb_omni_database_tde_temp_blocks_encrypted_count_totalNumber of temporary blocks encrypted. Not applicable counter alloydb_omni_database_tde_temp_decryption_time_us_totalTotal time spent in temporary block decryption. Not applicable microseconds counter alloydb_omni_database_tde_temp_encryption_time_us_totalTotal time spent in temporary block encryption. Not applicable microseconds counter alloydb_omni_database_tde_wal_blocks_decrypted_count_totalNumber of WAL blocks decrypted. Not applicable counter alloydb_omni_database_tde_wal_blocks_encrypted_count_totalNumber of WAL blocks encrypted. Not applicable counter alloydb_omni_database_tde_wal_decryption_time_us_totalTotal time spent in WAL block decryption. Not applicable microseconds counter alloydb_omni_database_tde_wal_encryption_time_us_totalTotal time spent in WAL block encryption. Not applicable microseconds counter