Creating a database cluster with TDE enabled
============================================

You enable transparent data encryption when you initialize a database
cluster using `initdb <https://www.postgresql.org/docs/15/app-initdb.html>`_  .

Using initdb TDE options
------------------------

To enable encryption, use the following options with the ``initdb``
command or their fallback environment variables:

``-y, --data-encryption``

Initialize the new database cluster with transparent data encryption.
See for more information. Optionally specify an AES key length. Valid
values are 128 and 256. The default is 128.

``--copy-key-from=<file>``

Copy the data encryption key from the given location. You can use this
option to copy a key from an existing cluster when preparing a new
cluster as a target for pg_upgrade. ``--key-wrap-command=<command>``
Specify a command to wrap (encrypt) the generated data encryption key.
The command must include a placeholder ``%p`` that specifies the file to
write the wrapped key to. The unwrapped key is provided to the command
on its standard input. If you don’t specify this option, the environment
variable ``PGDATAKEYWRAPCMD`` is used. Use the special value ``-`` if
you don’t want to apply any key wrapping command. You must specify this
option or the environment variable fallback if you’re using data
encryption. See :ref:`Securing the data encryption key <Securing the data encryption key>`  for more information.

``--key-unwrap-command=<command>``

Specify a command to unwrap (decrypt) the data encryption key. The
command must include a placeholder ``%p`` that specifies the file to
read the wrapped key from. The command needs to write the unwrapped key
to its standard output. If you don’t specify this option, the
environment variable ``PGDATAKEYUNWRAPCMD`` is used. Use the special
value ``-`` if you don’t want to apply any key unwrapping command. You
must specify this option or the environment variable fallback if you’re
using data encryption. See :ref:`Securing the data encryption key <Securing the data encryption key>`  for more information.
``--no-key-wrap``

Disable key wrapping. The data encryption key is instead stored in
plaintext in the data directory. (This option is a shortcut for setting
both the wrap and the unwrap command to the special value ``-`` .)

..  Note::
   Using this option isn't secure. Use it only for testing purposes.  If you select data encryption and don't specify this option, then you must provide key wrap and unwrap commands. Otherwise, `initdb`  terminates with an error.

Using environment variables
---------------------------

To simplify operations, you can set the key wrap and unwrap commands in
the environment variables.

For example:

.. code:: shell

   PGDATAKEYWRAPCMD=openssl enc -e -aes128-wrap -pbkdf2 -out "%p"
   PGDATAKEYUNWRAPCMD=openssl enc -d -aes128-wrap -pbkdf2 -in "%p"
   export PGDATAKEYWRAPCMD PGDATAKEYUNWRAPCMD

Setting the key parameter in postgresql.conf
--------------------------------------------

When you enable TDE for a cluster, the ``initdb`` command initializes
the ``data_encryption_key_unwrap_command`` parameter in the
``postgresql.conf`` configuration file. The string specified in
``data_encryption_key_unwrap_command`` unwraps (decrypts) the data
encryption key.

The command 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.

If you don’t specify this parameter, the environment variable
``PGDATAKEYUNWRAPCMD`` is used.

Use the special value ``-`` if you don’t want to apply any key
unwrapping command.

You must specify this parameter or the environment variable fallback if
you’re using data encryption. See :ref:`Securing the data encryption key <Securing the data encryption key>`  for more information.

You can set this parameter only at server start.

This parameter is normally initialized by ``initdb`` . Change it only if
you change the key wrap method.

For more information on the configuration files, see `PostgreSQL File Locations documentation <https://www.postgresql.org/docs/15/runtime-config-file-locations.html>`_  .

Example
-------

This example uses EDB Postgres Advanced Server 15 running on a Linux
platform. It uses openssl to define the passkey to wrap and unwrap the
generated data encryption key.

1. Set the data encryption key (wrap) and decryption (unwrap)
   environment variables:

edb_notranlate_1  ..  Note::
   If you are on Windows you don't need the single quotes around the variable value.

1. Initialize the cluster using ``initdb`` with encryption enabled. This
   command sets the ``data_encryption_key_unwrap_command`` parameter in
   the postgresql.conf file.

.. code:: shell

      /usr/edb/as15/bin/initdb --data-encryption -D /var/lib/edb/as15/data 

1. Start the cluster:

.. code:: shell

      /usr/edb/as15/bin/pg_ctl -D /var/lib/edb/as15/data start

1. Run grep on postgresql.conf to see the setting of
   ``data_encryption_key_unwrap_command`` :

.. code:: shell

      grep data_encryption_key_unwrap_command /var/lib/edb/as15/data/postgresql.conf
      __OUTPUT__
      data_encryption_key_unwrap_command = openssl enc -d -aes-128-cbc -pass pass:ok -in %p

Checking for TDE presence using SQL
-----------------------------------

You can find out whether TDE is present on a server by querying the
``data_encryption_version`` column of the ``pg_control_init`` table.

A value of 0 means TDE isn’t enabled. Any nonzero value reflects the
version of TDE in use. Currently, when TDE is enabled, this value is 1.

.. code:: sql

   select data_encryption_version from pg_control_init();
   __OUTPUT__
    data_encryption_version
   - ------------------------
                          1
   (1 row)
