Cluster File Encryption Cluster File Encryption The purpose of cluster file encryption is to prevent users with read access to the directories used to store database files and write-ahead log from being able to access the data stored in those files. For example, when using cluster file encryption, users who have read access to the cluster directories for backup purposes will not be able to decrypt the data stored in these files. Cluster file encryption uses two levels of encryption. The first level is data encryption keys, specifically keys zero and one. Key zero is the key used to encrypt database heap and index files which are stored in the file system, plus temporary files created during database operation. Key one is used to encrypt write-ahead log (WAL) files. Two different keys are used so that primary and standby servers can use different zero (heap/index/temp) keys, but the same one (WAL) key, so that these keys can eventually be rotated by switching the primary to the standby and then changing the WAL key. The second level of encryption is a key used to encrypt first-level keys. This type of key is often referred to as a Key Encryption Key (KEK). This key is not stored in the file system, but provided at initdb time and each time the server is started. This key prevents anyone with access to the database directories from decrypting the data because they do not know the second-level key which encrypted the first-level keys which encrypted the database cluster files. Initialization Cluster file encryption is enabled when PostgreSQL is built with --with-openssl and is specified during initdb. The cluster key provided by the option during initdb and the one generated by in the postgresql.conf must match for the database cluster to start. Note that the cluster key command passed to initdb must return a key of 64 hexadecimal characters. For example. initdb -D dbname --cluster-key-command='ckey_passphrase.sh' Internals During the initdb process, if is specified, two data-level encryption keys are created. These two keys are then encrypted with the key encryption key (KEK) supplied by the cluster key command before being stored in the database directory. The key or passphrase that derives the key must be supplied from the terminal or stored in a trusted key store, such as key vault software, hardware security module. If the PostgreSQL server has been initialized to require a cluster key, each time the server starts the postgresql.conf cluster_key_command command will be executed and the cluster key retrieved. The data encryption keys in the pg_cryptokeys directory will then be decrypted using the supplied key and integrity-checked to ensure it matches the initdb-supplied key. If this check fails, the server will refuse to start. The data encryption keys are randomly generated and are 128, 192, or 256-bits in length. They are encrypted by the key encryption key (KEK) using Advanced Encryption Standard (AES256) encryption in Galois/Counter Mode (GCM), which also provides KEK authentication.