Securing the data encryption key
================================

Data encryption key
-------------------

The key for transparent data encryption (the data key) is generated by
``initdb`` and stored in a file ``pg_encryption/key.bin`` under the data
directory. This file actually contains several keys that are used for
different purposes at run time. The data key is a single sequence of
random bytes in the file.

Without any further action, this file contains the key in plaintext,
which isn’t secure. Anyone with access to the encrypted data directory
has access to the plaintext key, which defeats the purpose of
encryption.

Choosing a mechanism to protect the data encryption key
-------------------------------------------------------

To secure the data encryption key, you must specify a wrap and a unwrap
command that provides TDE with a data encryption protection mechanism.
You can set this parameter only at server start.

With the wrap and unwrap commands you can:

-  :ref:`Using a passphrase <Using a passphrase>`  . A wrapping key is derived from the passphrase and
   used to encrypt the data key.

-  :ref:`Using a key store <Using a key store>`  or key store. This second key is also called the
   *key-wrapping key* or *master key*.

-  You can also choose to :ref:`Disabling the key wrapping <Disabling the key wrapping>`  . Do this only for test
   environments, as it leaves the TDE key unprotected.

Configuring a wrapping and unwrapping command
---------------------------------------------

After you have chosen a method to protect your key, you can create the
wrapping/unwrapping commands. The configuration of these commands is
left to the user, which allows tailoring the setup to local requirements
and integrating with existing key management software or similar.

The :ref:`Using a passphrase <Using a passphrase>`  topic provides an example for wrapping/unwrapping
commands using OpenSSL and a passphrase to secure the TDE data key. The
:ref:`Using a key store <Using a key store>`  topic provides an example for wrapping/unwrapping commands
using an external key store key to protect the TDE data key.

When you initialize a server with TDE, the ``initdb`` command adds the
``data_encryption_key_unwrap_command`` parameter in the
``postgresql.conf`` configuration file. The string specified in
``data_encryption_key_unwrap_command`` is then able to unwrap (decrypt)
the data encryption key.

The commands must contain a placeholder ``%p`` , which is replaced with
the name of the file containing the key to unwrap. The command must
print the unwrapped (decrypted) key to its standard output.

Providing the wrapping and unwrapping commands to TDE
-----------------------------------------------------

You must make the commands available to the TDE database server so it
can wrap and unwrap the data encryption key. You have the following
options:

-  You can configure the wrapping and unwrapping commands as environment
   variables before creating the database, so TDE can fall back on those
   variables when initializing a server.

.. raw:: html

   <details>

.. raw:: html

   <summary>

Example

.. raw:: html

   </summary>

.. code:: shell

     PGDATAKEYWRAPCMD=openssl enc -e -aes128-wrap -pbkdf2 -out "%p"
     PGDATAKEYUNWRAPCMD=openssl enc -d -aes128-wrap -pbkdf2 -in "%p"
     export PGDATAKEYWRAPCMD PGDATAKEYUNWRAPCMD
     #After these variables are set, you can initialize the server:
     initdb --data-encryption -D /var/lib/edb/as16/data

.. raw:: html

   </details>

-  You can provide the wrapping and unwrapping commands directly in the
   command line when initializing a server with the
   ``--key-wrap-command=<command>`` and
   ``--key-unwrap-command=<command>`` options.

.. raw:: html

   <details>

.. raw:: html

   <summary>

Example

.. raw:: html

   </summary>

.. code:: shell

     initdb --data-encryption -D /var/lib/edb/as16/data --key-wrap-command=openssl enc -e -aes128-wrap -pbkdf2 -out "%p" --key-unwrap-command=openssl enc -d -aes128-wrap -pbkdf2 -in "%p"

.. raw:: html

   </details>

-  You can disable the protection of your data encryption key with
   ``--no-key-wrap`` . This leaves your key unprotected and is
   recommended for testing proposes only.

.. raw:: html

   <details>

.. raw:: html

   <summary>

Example

.. raw:: html

   </summary>

.. code:: shell

     initdb --data-encryption -D /var/lib/edb/as16/data --no-key-wrap

.. raw:: html

   </details>

.. toctree::
  :maxdepth: 3

  Administering--secure_key--passphrase
  Administering--secure_key--key_store
  Administering--secure_key--disabling_key
  Administering--secure_key--key_rotation
