Set up multi-tenancy¶
The steps below describe how to set up multi-tenancy with pg_tde
. Multi-tenancy allows you to encrypt different databases with different keys. This provides granular control over data and enables you to introduce different security policies and access controls for each database so that only authorized users of specific databases have access to the data.
If you don’t need multi-tenancy, use the global key provider. See the configuration steps from the Setup section.
For how to enable WAL encryption, refer to the WAL encryption section.
Considerations¶
You can use the following options to manage encryption keys:
-
Use the Key Management Store (KMS). This is the recommended approach.
pg_tde
supports the following KMS:- HashiCorp Vault as the key/value secrets engine version 2 with secret versioning
- HashiCorp Vault as the KMIP server. The KMIP server is part of Vault Enterprise and requires a license
- OpenBao as the open-source alternative to HashiCorp Vault KMIP
- A KMIP-compatible server. For testing and development purposes you can use PyKMIP
The KMS configuration is out of scope of this document. We assume that you have the KMS up and running. For the
pg_tde
configuration, you need the following information:- The secret access token to the Vault server
- The URL to access the Vault server
- (Optional) The CA file used for SSL verification
- The hostname or IP address of the KMIP server.
- The valid certificates issued by the key management appliance.
-
Use the local keyfile. Use the keyfile only development and testing purposes since the keys are stored unencrypted.
Enable extension¶
Load the pg_tde
at startup time. The extension requires additional shared memory; therefore, add the pg_tde
value for the shared_preload_libraries
parameter and restart the postgresql
cluster.
-
Use the ALTER SYSTEM command from
psql
terminal to modify theshared_preload_libraries
parameter. This requires superuser privileges.ALTER SYSTEM SET shared_preload_libraries = 'pg_tde';
-
Start or restart the
postgresql
cluster to apply the changes.- On Debian and Ubuntu:
sudo systemctl restart postgresql-17
- On RHEL and derivatives
sudo systemctl restart postgresql-17
-
Create the extension using the CREATE EXTENSION command. You must have the privileges of a superuser or a database owner to use this command. Connect to
psql
as a superuser for a database and run the following command:CREATE EXTENSION pg_tde;
The
pg_tde
extension is created for the currently used database. To enable data encryption in other databases, you must explicitly run theCREATE EXTENSION
command against them.Tip
You can have the
pg_tde
extension automatically enabled for every newly created database. Modify the templatetemplate1
database as follows:psql -d template1 -c 'CREATE EXTENSION pg_tde;'
Key provider configuration¶
You must do these steps for every database where you have created the extension.
-
Set up a key provider.
Make sure you have obtained the root certificate for the KMIP server and the keypair for the client. The client key needs permissions to create / read keys on the server. Find the configuration guidelines for the HashiCorp Vault Enterprise KMIP Secrets Engine.
For testing purposes, you can use the PyKMIP server which enables you to set up required certificates. To use a real KMIP server, make sure to obtain the valid certificates issued by the key management appliance.
SELECT pg_tde_add_key_provider_kmip('provider-name','kmip-addr', 5696, '/path_to/server_certificate.pem', '/path_to/client_key.pem');
where:
provider-name
is the name of the provider. You can specify any name, it’s for you to identify the provider.kmip-addr
is the IP address of a domain name of the KMIP serverport
is the port to communicate with the KMIP server. Typically used port is 5696.server-certificate
is the path to the certificate file for the KMIP server.client key
is the path to the client key.
Warning: This example is for testing purposes only:
SELECT pg_tde_add_key_provider_kmip('kmip','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_key_jane_doe.pem');
The Vault server setup is out of scope of this document.
SELECT pg_tde_add_key_provider_vault_v2('provider-name','root_token','url','mount','ca_path');
where:
url
is the URL of the Vault servermount
is the mount point where the keyring should store the keysroot_token
is an access token with read and write access to the above mount point- [optional]
ca_path
is the path of the CA file used for SSL verification
Warning: This example is for testing purposes only:
SELECT pg_tde_add_key_provider_file_vault_v2('my-vault','http://vault.vault.svc.cluster.local:8200,'secret/data','hvs.zPuyktykA...example...ewUEnIRVaKoBzs2', NULL);
This setup is intended for development and stores the keys unencrypted in the specified data file.
SELECT pg_tde_add_key_provider_file('provider-name','/path/to/the/keyring/data.file');
Warning: This example is for testing purposes only:
SELECT pg_tde_add_key_provider_file('file-keyring','/tmp/pg_tde_test_local_keyring.per');
-
Add a principal key
SELECT pg_tde_set_principal_key('name-of-the-principal-key', 'provider-name','ensure_new_key');
where:
name-of-the-principal-key
is the name of the principal key. You will use this name to identify the key.provider-name
is the name of the key provider you added before. The principal key will be associated with this provider.ensure_new_key
defines if a principal key must be unique. The default valuetrue
means that you must speficy a unique key during key rotation. Thefalse
value allows reusing an existing principal key.
Warning: This example is for testing purposes only:
SELECT pg_tde_set_principal_key('test-db-master-key','file-vault','ensure_new_key');
The key is auto-generated.
Info: The key provider configuration is stored in the database catalog in an unencrypted table. See how to use external reference to parameters to add an extra security layer to your setup.