From 828a42a81be1b3c6a6cd4a83975222027df64dab Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Fri, 7 Feb 2025 14:00:49 +0000 Subject: [PATCH] PG-1354: Update documentation with latest changes (#46) --- .../_resource/overrides/main.html | 48 +++++- .../_resource/overrides/partials/banner.html | 9 ++ .../pg_tde/documentation/docs/css/design.css | 81 +++++++++- .../pg_tde/documentation/docs/css/extra.css | 16 +- contrib/pg_tde/documentation/docs/decrypt.md | 15 +- contrib/pg_tde/documentation/docs/faq.md | 144 +++++++++++++++++- contrib/pg_tde/documentation/docs/get-help.md | 24 +++ contrib/pg_tde/documentation/docs/index.md | 10 +- contrib/pg_tde/documentation/docs/install.md | 38 +++-- contrib/pg_tde/documentation/docs/setup.md | 6 +- contrib/pg_tde/documentation/docs/test.md | 20 ++- contrib/pg_tde/documentation/mkdocs-pdf.yml | 2 +- contrib/pg_tde/documentation/mkdocs.yml | 6 +- .../documentation/snippets/services-banner.md | 13 -- 14 files changed, 361 insertions(+), 71 deletions(-) create mode 100644 contrib/pg_tde/documentation/_resource/overrides/partials/banner.html create mode 100644 contrib/pg_tde/documentation/docs/get-help.md delete mode 100644 contrib/pg_tde/documentation/snippets/services-banner.md diff --git a/contrib/pg_tde/documentation/_resource/overrides/main.html b/contrib/pg_tde/documentation/_resource/overrides/main.html index 4ef03fedaef..394932bb9ec 100644 --- a/contrib/pg_tde/documentation/_resource/overrides/main.html +++ b/contrib/pg_tde/documentation/_resource/overrides/main.html @@ -24,14 +24,46 @@ {% endif %} - - - - {% endblock %} - + + + {% endblock %} + +{% block site_nav %} + {% if nav %} + {% if page.meta and page.meta.hide %} + {% set hidden = "hidden" if "navigation" in page.meta.hide %} + {% endif %} + + {% endif %} + {% if "toc.integrate" not in features %} + {% if page.meta and page.meta.hide %} + {% set hidden = "hidden" if "toc" in page.meta.hide %} + {% endif %} + + {% endif %} + + {% endblock %} diff --git a/contrib/pg_tde/documentation/_resource/overrides/partials/banner.html b/contrib/pg_tde/documentation/_resource/overrides/partials/banner.html new file mode 100644 index 00000000000..fb26631493f --- /dev/null +++ b/contrib/pg_tde/documentation/_resource/overrides/partials/banner.html @@ -0,0 +1,9 @@ +
+

+

For help, click the link below to get free database assistance or contact our experts for personalized support.

+ + +
\ No newline at end of file diff --git a/contrib/pg_tde/documentation/docs/css/design.css b/contrib/pg_tde/documentation/docs/css/design.css index 761e52cc058..2e14d20e585 100644 --- a/contrib/pg_tde/documentation/docs/css/design.css +++ b/contrib/pg_tde/documentation/docs/css/design.css @@ -77,6 +77,7 @@ [data-md-color-scheme="percona-light"] { /* Primitives */ + --md-hue: 220; --md-primary-fg-color: var(--sky700); /* Type */ @@ -85,6 +86,7 @@ /* Defaults */ --md-default-bg-color: var(--white); + --md-default-fg-color: var(--stone900); --md-default-fg-color--light: rgba(44,50,62,0.72); --md-default-fg-color--lighter: rgba(44,50,62,0.40); --md-default-fg-color--lightest: rgba(44,50,62,0.25); @@ -102,11 +104,14 @@ /* Code */ --md-code-bg-color: var(--stone800); --md-code-bg-color: var(--stone50); + + /* Tables */ + --md-typeset-table-color: hsla(var(--md-hue),17%,21%,0.25) } [data-md-color-scheme="percona-dark"] { /* Primitives */ - --md-hue: 230; + --md-hue: 0; --md-primary-fg-color: var(--sky200); /* Type */ @@ -115,6 +120,7 @@ /* Defaults */ --md-default-bg-color: var(--stone900); + --md-default-fg-color: var(--white); --md-default-fg-color--light: rgba(251,251,251,0.72); --md-default-fg-color--lighter: rgba(251,251,251,0.4); --md-default-fg-color--lightest: rgba(209,213,222,0.25); @@ -133,6 +139,9 @@ /* Code */ --md-code-bg-color: var(--stone50); --md-code-bg-color: var(--stone800); + + /* Tables */ + --md-typeset-table-color: hsla(var(--md-hue),0%,100%,0.25) } /* Typography */ @@ -155,7 +164,7 @@ .md-typeset h1 { margin: 0 0 0.75em; } -.md-header { +.md-header :not(.md-search__suggest) { font-family: var(--fHeading); font-weight: bold; } @@ -208,12 +217,20 @@ .md-tabs__link { margin-top: 0.55rem; } -.md-header__topic { - transition: opacity .25s; -} -.md-header__topic:hover { - opacity: 0.7; +/* .md-header__topic .md-ellipsis { + position: relative; } +.md-header__topic:hover .md-ellipsis::after { + content: ""; + position: absolute; + display: block; + right: 0; + bottom: 11px; + left: 0; + width: 100%; + height: 2.5px; + background-color: currentColor; +} */ /* Footer */ @@ -254,6 +271,13 @@ vertical-align: baseline; padding: 0 0.2em 0.1em; border-radius: 0.15em; + white-space: pre-wrap; /* Ensure long lines wrap */ +} +.md-typeset .highlight code span, +.md-typeset code, +.md-typeset kbd, +.md-typeset pre { + color: var(--md-typeset-color); } .md-button code, [data-md-color-scheme="percona-dark"] .md-button:not(.md-button--primary) code { @@ -636,6 +660,7 @@ i[warning] [class*="moji"] { -moz-appearance: none; appearance: none; align-self: center; + font-family: var(--fHeading); font-size: 0.9rem; line-height: 1; font-weight: 700; @@ -650,6 +675,46 @@ i[warning] [class*="moji"] { display: none; } +/* Mike Version Select */ + +.md-version__current, +.md-version__link { + font-size: 0.9rem; + font-weight: 700; + line-height: 1; + padding: 0.5em; +} +.md-version__current { + top: unset; + margin-left: 0.25em !important; + margin-right: 0.25em !important; + border-radius: 0.1rem; + background-color: rgba(0,0,0,0.2); +} +.md-version__current::after { + width: 0.5em; + height: 0.75em; +} +.md-version__list { + top: 0.1em; + margin: 0.25em; + border-radius: 0.1rem; +} +[dir="ltr"] .md-version__current::after { + margin-left: 0.4em; +} +[dir="rtl"] .md-version__current::after { + margin-right: 0.4em; +} +[dir="ltr"] .md-version__link { + padding-left: 0.5em; + padding-right: 1.4375em; +} +[dir="rtl"] .md-version__link { + padding-left: 1.4375em; + padding-right: 0.5em; +} + /* Media queries */ @media screen and (max-width: 76.1875em) { @@ -667,4 +732,4 @@ i[warning] [class*="moji"] { padding: 1em; } } -/**/ +/**/ \ No newline at end of file diff --git a/contrib/pg_tde/documentation/docs/css/extra.css b/contrib/pg_tde/documentation/docs/css/extra.css index 30f5a627800..c857532bb87 100644 --- a/contrib/pg_tde/documentation/docs/css/extra.css +++ b/contrib/pg_tde/documentation/docs/css/extra.css @@ -1,7 +1,13 @@ @media print { /* Adjusts positioning of admonition icon */ - .md-typeset :is(.admonition-title,summary):before { - top: 0.6rem; - left: 0.6rem; - } - } \ No newline at end of file + .md-typeset :is(.admonition-title,summary):before { + top: 0.6rem; + left: 0.6rem; + } + +} + +.md-sidebar__inner { + font-size: 0.65rem; /* Font size */ + line-height: 1.6; +} \ No newline at end of file diff --git a/contrib/pg_tde/documentation/docs/decrypt.md b/contrib/pg_tde/documentation/docs/decrypt.md index c29ee6c1329..f3ae2060658 100644 --- a/contrib/pg_tde/documentation/docs/decrypt.md +++ b/contrib/pg_tde/documentation/docs/decrypt.md @@ -8,6 +8,12 @@ If you encrypted a table with the `tde_heap` or `tde_heap_basic` access method a ALTER TABLE mytable SET access method heap; ``` +Note that the `ALTER TABLE SET` command drops hint bits and this may affect the performance. Running a plain `SELECT, count(*)`, or `VACUUM` commands on the entire table will check every tuple for visibility and set its hint bits. Therefore, after executing the ALTER command, run a simple "count(*)" on your tables: + +``` +SELECT COUNT(*) FROM mytable; +``` + Check that the table is not encrypted: ``` @@ -25,6 +31,13 @@ The output returns `f` meaning that the table is no longer encrypted. ``` Note that the indexes and WAL files will no longer be encrypted. + + Run a simple "count(*)" on your table to check every tuple for visibility and set the hint bits: + + ``` + SELECT COUNT(*) FROM mytable; + ``` + ## Method 2. Create a new unencrypted table on the base of the encrypted one @@ -41,4 +54,4 @@ The new table `Customers` inherits the structure and the data from `EncryptedCus ``` DROP TABLE EncryptedCustomers; -``` \ No newline at end of file +``` diff --git a/contrib/pg_tde/documentation/docs/faq.md b/contrib/pg_tde/documentation/docs/faq.md index 9e9d5afdf84..dc09a5f08dc 100644 --- a/contrib/pg_tde/documentation/docs/faq.md +++ b/contrib/pg_tde/documentation/docs/faq.md @@ -2,18 +2,53 @@ ## Why do I need TDE? -- Compliance to security and legal regulations like GDPR, PCI DSS and others -- Encryption of backups -- Granular encryption of specific data sets and reducing the performance overhead that encryption brings +- Compliance to security and legal regulations like General Data Protection Regulation (GDPR), Payment Card Industry Data Security Standard (PCI DSS), California Consumer Privacy Act (CCPA), Data Protection Act 2018 (DPA 2018) and others +- Encryption of backups. Even when an authorized person gets physical access to a backup, encryption ensures that the data remains unreadable and secure. +- Granular encryption of specific data sets and reducing the performance overhead that encryption brings. - Additional layer of security to existing security measures +## When and how should I use TDE? + +If you are dealing with Personally Identifiable Information (PII), data encryption is crucial. Especially if you are involved in areas with strict regulations like: + +* financial services where TDE helps to comply with PCI DSS +* healthcare and insurance - compliance with HIPAA, HITECH, CCPA +* telecommunications, government and education to ensure data confidentiality. + +Using TDE helps you avoid the following risks: + +* Data breaches +* Identity theft that may lead to financial fraud and other crimes +* Reputation damage leading to loss of customer trust and business +* Legal consequences and financial losses for non-compliance with data protection regulations +* Internal threats by misusing unencrypted sensitive data + +If to translate sensitive data to files stored in your database, these are user data in tables, temporary files, WAL files. TDE has you covered encrypting all these files. + +`pg_tde` does not encrypt system catalogs yet. This means that statistics data and database metadata are not encrypted. The encryption of system catalogs is planned for future releases. + + ## I use disk-level encryption. Why should I care about TDE? -Encrypting a hard drive encrypts all data including system and application files that are there. However, disk encryption doesn’t protect your data after the boot-up of your system. During runtime, the files are decrypted with disk-encryption. +Encrypting a hard drive encrypts all data, including system, application, and temporary files. + +Full disk encryption protects your data from people who have physical access to your device and even if it is lost or stolen. However, it doesn't protect the data after system boot-up: the data is automatically decrypted when the system runs or when an authorized user requests it. + +Another point to consider is PCI DSS compliance for Personal Account Numbers (PAN) encryption. + +* **PCI DSS 3.4.1** standards might consider disk encryption sufficient for compliance if you meet these requirements: + + * Separate the logical data access from the operating system authentication. + + * Ensure the decryption key is not linked to user accounts. + + Note that PCI DSS 3.4.1 is retiring on March 31, 2025. Therefore, consider switching to PCI DSS 4.0. + +* **PCI DSS 4.0** standards consider using only disk and partition-level encryption not enough to ensure PAN protection. It requires an additional layer of security that `pg_tde` can provide. -TDE focuses specifically on data files and offers a more granular control over encrypted data. It also ensures that files are encrypted on disk during runtime and when moved to another system or storage. +`pg_tde` focuses specifically on data files and offers more granular control over encrypted data. The data remains encrypted on disk during runtime and when you move it to another directory, another system or storage. An example of such data is backups. They remain encrypted when moved to the backup storage. -Consider using TDE and storage-level encryption together to add another layer of data security +Thus, to protect your sensitive data, consider using TDE to encrypt it at the table level. Then use disk-level encryption to encrypt a specific volume where this data is stored, or the entire disk. ## Is TDE enough to ensure data security? @@ -25,6 +60,101 @@ No. TDE is an additional layer to ensure data security. It protects data at rest * Regular monitoring and auditing * Additional data protection for sensitive fields (e.g., application-layer encryption) +## How does `pg_tde` make my data safe? + +`pg_tde` uses two keys to encrypt data: + +* Internal encryption keys to encrypt the data. These keys are stored internally in an encrypted format, in a single `$PGDATA/pg_tde` directory. +* Principal keys to encrypt internal encryption keys. These keys are stored externally, in the Key Management System (KMS). + +You can use the following KMSs: + +* [HashiCorp Vault](https://developer.hashicorp.com/vault/docs/what-is-vault). `pg_tde` supports the KV secrets engine v2 of Vault. +* [OpenBao](https://openbao.org/) implementation of Vault +* KMIP-compatible server. KMIP is a standardized protocol for handling cryptographic workloads and secrets management + +HashiCorp Vault can also act as the KMIP server, managing cryptographic keys for clients that use the KMIP protocol. + +Here’s how encryption of data files works: + +First, data files are encrypted with internal keys. Each file that has a different OID, has an internal key. For example, a table with 4 indexes will have 5 internal keys - one for the table and one for each index. + +The initial decision on what file to encrypt is based on the table access method in PostgreSQL. When you run a `CREATE` or `ALTER TABLE` statement with the `USING tde_heap` clause, the newly created data files are marked as encrypted, and then file operations encrypt/decrypt the data. Later, if an initial file is re-created as a result of a `TRUNCATE` or `VACUUM FULL` command, the newly created file inherits the encryption information and is either encrypted or not. + +The principal key is used to encrypt the internal keys. The principal key is stored in the key management store. When you query the table, the principal key is retrieved from the key store to decrypt the table. Then the internal key for that table is used to decrypt the data. + +WAL encryption is done globally for the entire database cluster. All modifications to any database within a PostgreSQL cluster are written to the same WAL to maintain data consistency and integrity and ensure that PostgreSQL cluster can be restored to a consistent state. Therefore, WAL is encrypted globally. + +When you turn on WAL encryption, `pg_tde` encrypts entire WAL pages except for the header. The header contains a marker if a page is encrypted or not. + +The same 2-tier approach is used with WAL as with the table data: WAL pages are first encrypted with the internal key. Then the internal key is encrypted with the global principal key. + +You can turn WAL encryption on and off so WAL can contain both encrypted and unencrypted pages. The WAL encryption GUC variable influences only writes. + +Whenever the WAL is being read (by the recovery process or tools), the decision on what pages should be decrypted is based solely on the encryption flag of each page. + + +## Should I encrypt all my data? + +It depends on your business requirements and the sensitivity of your data. Encrypting all data is a good practice but it can have a performance impact. + +Consider encrypting only tables that store sensitive data. You can decide what tables to encrypt and with what key. The [Setup](setup.md) section in documentation focuses on this approach. + +We advise encrypting the whole database only if all your data is sensitive, like PII, or if there is no other way to comply with data safety requirements. See [How to configure global encryption](global-encryption.md). + +## What cipher mechanisms are used by `pg_tde`? + +`pg_tde` currently uses a AES-CBC-128 algorithm. First the internal keys in the datafile are encrypted using the principal key with AES-CBC-128, then the file data itself is again encrypted using AES-CBC-128 with the internal key. + +For WAL encryption, AES-CTR-128 is used. + +The support of other encryption mechanisms such as AES256 is planned for future releases. Reach out to us with your requirements and usage scenarios of other encryption methods are needed. + +## Is post-quantum encryption supported? + +No, it's not yet supported. In our implementation we reply on OpenSSL libraries that don't yet support post-quantum encryption. + +## Can I encrypt an existing table? + +Yes, you can encrypt an existing table. Run the ALTER TABLE command as follows: + +``` +ALTER TABLE table_name SET ACCESS METHOD tde_heap; +``` + +Since the `ALTER TABLE SET` command drops hint bits and this may affect the performance, we recommend to run the `SELECT COUNT(*)` command. It checks every tuple for visibility and sets its hint bits. Read more in the [Changing existing table](test.md) section. + +## Do I have to restart the database to encrypt the data? + +You must restart the database in the following cases to apply the changes: + +* after you enabled the `pg_tde` extension +* to turn on / off the WAL encryption + +After that, no database restart is required. When you create or alter the table using the `tde_heap` access method, the files are marked as those that require encryption. The encryption happens at the storage manager level, before a transaction is written to disk. Read more about [how tde_heap works](table-access-method.md#how-tde_heap-works). + ## What happens to my data if I lose a principal key? -If you lose encryption keys, especially, the principal key, the data is lost. That's why it's critical to back up your encryption keys securely. \ No newline at end of file +If you lose encryption keys, especially, the principal key, the data is lost. That's why it's critical to back up your encryption keys securely and use the Key Management service for key management. + +## Can I use `pg_tde` in a multi-tenant setup? + +Multi-tenancy is the type of architecture where multiple users, or tenants, share the same resource. It can be a database, a schema or an entire cluster. + +In `pg_tde`, multi-tenancy is supported via a separate principal key per database. This means that a database owner can decide what tables to encrypt within a database. The same database can have both encrypted and non-encrypted tables. + +To control user access to the databases, you can use role-based access control (RBAC). + +WAL files are encrypted globally across the entire PostgreSQL cluster using the same encryption key. Users don't interact with WAL files as these are used by the database management system to ensure data integrity and durability. + +## Are my backups safe? Can I restore from them? + +`pg_tde` encrypts data at rest. This means that data is stored on disk in an encrypted form. During a backup, already encrypted data files are copied from disk onto the storage. This ensures the data safety in backups. + +Since the encryption happens on the database level, it makes no difference for your tools and applications. They work with the data in the same way. + +To restore from an encrypted backup, you must have the same principal encryption key, which was used to encrypt files in your backup. + +## I'm using OpenSSL in FIPS mode and need to use `pg_tde`. Does `pg_tde` comply with FIPS requirements? Can I use my own FIPS-mode OpenSSL library with `pg_tde`? + +Yes. `pg_tde` works with the FIPS-compliant version of OpenSSL, whether it is provided by your operating system or if you use your own OpenSSL libraries. If you use your own libraries, make sure they are FIPS certified. diff --git a/contrib/pg_tde/documentation/docs/get-help.md b/contrib/pg_tde/documentation/docs/get-help.md new file mode 100644 index 00000000000..3155a0cb426 --- /dev/null +++ b/contrib/pg_tde/documentation/docs/get-help.md @@ -0,0 +1,24 @@ +# Get help from Percona + +Our documentation guides are packed with information, but they can't cover everything you need to know about `pg_tde`. They also won't cover every scenario you might come across. Don't be afraid to try things out and ask questions when you get stuck. + +## Percona's Community Forum + +Be a part of a space where you can tap into a wealth of knowledge from other database enthusiasts and experts who work with Percona's software every day. While our service is entirely free, keep in mind that response times can vary depending on the complexity of the question. You are engaging with people who genuinely love solving database challenges. + +We recommend visiting our [Community Forum](https://forums.percona.com/t/welcome-to-perconas-community-forum/7){:target="_blank"}. It's an excellent place for discussions, technical insights, and support around Percona database software. If you’re new and feeling a bit unsure, our [FAQ](https://forums.percona.com/faq){:target="_blank"} and [Guide for New Users](https://forums.percona.com/t/faq-guide-for-new-users/8562){:target="_blank"} ease you in. + +If you have thoughts, feedback, or ideas, the community team would like to hear from you at [Any ideas on how to make the forum better?](https://forums.percona.com/t/any-ideas-on-how-to-make-the-forum-better/11522){:target="blank"}. We’re always excited to connect and improve everyone's experience. + +## Percona experts + +[Percona experts](https://www.percona.com/services/consulting){:target="_blank"} bring years of experience in tackling tough database performance issues and design challenges. We understand your challenges when managing complex database environments. That's why we offer various services to help you simplify your operations and achieve your goals. + +| Service | Description | +|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 24/7 Expert Support | Our dedicated team of database experts is available 24/7 to assist you with any database issues. We provide flexible support plans tailored to your specific needs. | +| Hands-On Database Management | Our managed services team can take over the day-to-day management of your database infrastructure, freeing up your time to focus on other priorities. | +| Expert Consulting | Our experienced consultants provide guidance on database topics like architecture design, migration planning, performance optimization, and security best practices. | +| Comprehensive Training | Our training programs help your team develop skills to manage databases effectively, offering virtual and in-person courses. | + +We're here to help you every step of the way. Whether you need a quick fix or a long-term partnership, we're ready to provide your expertise and support. \ No newline at end of file diff --git a/contrib/pg_tde/documentation/docs/index.md b/contrib/pg_tde/documentation/docs/index.md index bf3b12fd2e1..19677410721 100644 --- a/contrib/pg_tde/documentation/docs/index.md +++ b/contrib/pg_tde/documentation/docs/index.md @@ -2,9 +2,7 @@ `pg_tde` is the open source PostgreSQL extension that provides Transparent Data Encryption (TDE) to protect data at rest. This ensures that the data stored on disk is encrypted, and no one can read it without the proper encryption keys, even if they gain access to the physical storage media. -You can configure encryption differently for each database, encrypting specific tables in some databases with different encryption keys while keeping others unencrypted. - -Lear more [what is Transparent Data Encryption](tde.md#how-does-it-work) and [why you need it](tde.md#why-do-you-need-tde). +Learn more [what is Transparent Data Encryption](tde.md#how-does-it-work) and [why you need it](tde.md#why-do-you-need-tde). !!! important @@ -27,9 +25,9 @@ Lear more [what is Transparent Data Encryption](tde.md#how-does-it-work) and [wh * Keys in the local keyfile are stored unencrypted. For better security we recommend using the Key management storage. * System tables are currently not encrypted. -* Currently you cannot update the configuration of an existing Key Management Store (KMS). If its configuration changes (e.g. your Vault server has a new URL), you must set up a new key provider in `pg_tde` and create new keys there. Both the KMS and PostgreSQL servers must be up and running during these changes. [Reach out to our experts](https://www.percona.com/about/contact) for assistance and to outline the best update path for you. +* Currently you cannot update the configuration of an existing Key Management Store (KMS). If its configuration changes (e.g. your Vault server has a new URL), you must set up a new key provider in `pg_tde` and create new keys there. Both the KMS and PostgreSQL servers must be up and running during these changes. [Reach out to our experts](https://www.percona.com/about/contact) for help and to outline the best update path for you. - We plan to introduce the way to update the configuration of an existing KMS in future releases. + We plan to introduce the way to update the configuration of an existing KMS in future releases. * `pg_rewind` doesn't work with encrypted WAL for now. We plan to fix it in future releases. @@ -50,7 +48,7 @@ The `pg_tde` extension comes in two distinct versions with specific access metho ### Which version to chose? -The answer is pretty straightforward: for data sets where indexing is not mandatory or index encryption is not required, use the community version and the `tde_heap_basic` access method. Check the [upstream documentation :octicons-link-external-16:](https://github.com/percona/pg_tde/blob/main/README.md) how to get started. +Use the community version and the `tde_heap_basic` access method for data sets where indexing is not mandatory or index encryption is not required. Check the [upstream documentation :octicons-link-external-16:](https://github.com/percona/pg_tde/blob/main/README.md) how to get started. Otherwise, enjoy full encryption with the Percona Server for PostgreSQL version and the `tde_heap` access method. diff --git a/contrib/pg_tde/documentation/docs/install.md b/contrib/pg_tde/documentation/docs/install.md index daea87d462d..9d0722731a7 100644 --- a/contrib/pg_tde/documentation/docs/install.md +++ b/contrib/pg_tde/documentation/docs/install.md @@ -4,13 +4,27 @@ You can use the following options to manage encryption keys: -* Use the HashiCorp Vault server. This is the recommended approach. The Vault server configuration is out of scope of this document. We assume that you have the Vault server up and running. For the `pg_tde` configuration, you need the following information: +* Use the Key Management Store (KMS). This is the recommended approach. `pg_tde` supports the following KMS: - * The secret access token to the Vault server - * The URL to access the Vault server - * (Optional) The CA file used for SSL verification + * 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. -* Use the local keyfile. This approach is rather used for development and testing purposes since the keys are stored unencrypted in the specified keyfile. + 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: + + === "Vault secrets engine" + + * The secret access token to the Vault server + * The URL to access the Vault server + * (Optional) The CA file used for SSL verification + + === "KMIP server" + + * 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. ## Procedure @@ -34,7 +48,7 @@ Install `pg_tde` using one of available installation methods: === "Build from source" - To build `pg_tde` from source code, do the following + To build `pg_tde` from source code, do the following: 1. On Ubuntu/Debian: Install the following dependencies required for the build: @@ -64,11 +78,11 @@ Install `pg_tde` using one of available installation methods: !!! note - The steps below are for the `pg_tde` community version. + The steps below are for the PostgreSQL Community version of `pg_tde`. It provides the `tde_heap_basic` access method for data encryption. - To run `pg_tde` version for Percona Server for PostgreSQL, [use the Percona Distribution for PostgreSQL Docker image :octicons-link-external-16:](https://docs.percona.com/postgresql/17/docker.html). + To run the `pg_tde` version for Percona Server for PostgreSQL, [use the Percona Distribution for PostgreSQL Docker image :octicons-link-external-16:](https://docs.percona.com/postgresql/17/docker.html). - You can find Docker images built from the current main branch on [Docker Hub](https://hub.docker.com/r/perconalab/pg_tde). Images are built on top of [postgres:16](https://hub.docker.com/_/postgres) official image. + You can find Docker images on [Docker Hub](https://hub.docker.com/r/perconalab/pg_tde). Images are built on top of [postgres:16](https://hub.docker.com/_/postgres) official image. To run `pg_tde` in Docker, use the following command: @@ -76,9 +90,11 @@ Install `pg_tde` using one of available installation methods: docker run --name pg-tde -e POSTGRES_PASSWORD=mysecretpassword -d perconalab/pg_tde ``` - It builds and adds `pg_tde` extension to PostgreSQL 16. The `postgresql.conf` contains the required modifications. The `pg_tde` extension is added to `template1` so that all new databases automatically have the `pg_tde` extension loaded. + It builds and adds the `pg_tde` extension to PostgreSQL 16. The `postgresql.conf` contains the required modifications. The `pg_tde` extension is added to `template1` so that all new databases automatically have the `pg_tde` extension loaded. + + Keys are not created automatically. You must configure a key provider and a principal key for each database where you wish to use encrypted tables. - Keys are not created automatically. You must configure a key provider and a principal key for each database where you wish to use encrypted tables. See the instructions in the [Setup](setup.md) section, starting with the 4th point, as the first 3 steps are already completed in the Docker image. + Connect to the container and establish the `psql` session there. Then, see the instructions in the [Setup](setup.md) section, starting with the 4th point, as the first 3 steps are already completed in the Docker image. See [Docker Docs](https://hub.docker.com/_/postgres) on usage. diff --git a/contrib/pg_tde/documentation/docs/setup.md b/contrib/pg_tde/documentation/docs/setup.md index e6e6c7e03fb..037571e7ab6 100644 --- a/contrib/pg_tde/documentation/docs/setup.md +++ b/contrib/pg_tde/documentation/docs/setup.md @@ -64,8 +64,6 @@ Load the `pg_tde` at the start time. The extension requires additional shared me :material-information: Warning: This example is for testing purposes only: - The Vault server setup is out of scope of this document. - ``` SELECT pg_tde_add_key_provider_kmip('kmip','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_key_jane_doe.pem'); ``` @@ -88,7 +86,7 @@ Load the `pg_tde` at the start time. The extension requires additional shared me :material-information: Warning: This example is for testing purposes only: ``` - SELECT pg_tde_add_key_provider_file_vault_v2('my-vault','https://vault.example.com','secret/data','hvs.zPuyktykA...example...ewUEnIRVaKoBzs2', NULL); + 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); ``` === "With a keyring file" @@ -124,7 +122,7 @@ Load the `pg_tde` at the start time. The extension requires additional shared me :material-information: Info: The key provider configuration is stored in the database catalog in an unencrypted table. See [how to use external reference to parameters](external-parameters.md) to add an extra security layer to your setup. -## WAL encryption configuration +## WAL encryption configuration (tech preview) After you [enabled `pg_tde`](#enable-extension) and started the Percona Server for PostgreSQL, a principal key and a keyring for WAL are created. Now you need to instruct `pg_tde ` to encrypt WAL files by configuring WAL encryption. diff --git a/contrib/pg_tde/documentation/docs/test.md b/contrib/pg_tde/documentation/docs/test.md index ac6109532b6..88de38ac540 100644 --- a/contrib/pg_tde/documentation/docs/test.md +++ b/contrib/pg_tde/documentation/docs/test.md @@ -4,6 +4,8 @@ Enabling `pg_tde` extension for a database creates the table access method `tde_ Here's how to do it: +## Encrypt data in a new table + 1. Create a table in the database for which you have [enabled `pg_tde`](setup.md) using the `tde_heap` access method as follows: ``` @@ -41,11 +43,21 @@ Here's how to do it: SELECT pg_tde_rotate_principal_key('new-principal-key', 'new-provider'); -- changeprovider ``` -4. You can encrypt an existing table. It requires rewriting the table, so for large tables, it might take a considerable amount of time. +## Encrypt existing table - ``` - ALTER TABLE table_name SET access method tde_heap; - ``` +You can encrypt an existing table. It requires rewriting the table, so for large tables, it might take a considerable amount of time. + +Run the following command: + +``` +ALTER TABLE table_name SET access method tde_heap; +``` + +Note that the `ALTER TABLE SET` command drops hint bits and this may affect the performance. Running a plain `SELECT, count(*)`, or `VACUUM` commands on the entire table will check every tuple for visibility and set its hint bits. Therefore, after executing the ALTER command, run a simple "count(*)" on your tables: + +``` +SELECT COUNT(*) FROM table_name; +``` !!! hint diff --git a/contrib/pg_tde/documentation/mkdocs-pdf.yml b/contrib/pg_tde/documentation/mkdocs-pdf.yml index 0b76f278889..fc87289bae4 100644 --- a/contrib/pg_tde/documentation/mkdocs-pdf.yml +++ b/contrib/pg_tde/documentation/mkdocs-pdf.yml @@ -3,7 +3,7 @@ INHERIT: mkdocs.yml -copyright: Percona LLC, © 2024 +copyright: Percona LLC, © 2025 extra_css: - https://unicons.iconscout.com/release/v3.0.3/css/line.css diff --git a/contrib/pg_tde/documentation/mkdocs.yml b/contrib/pg_tde/documentation/mkdocs.yml index 639689812c0..0787ac71056 100644 --- a/contrib/pg_tde/documentation/mkdocs.yml +++ b/contrib/pg_tde/documentation/mkdocs.yml @@ -4,7 +4,7 @@ site_name: pg_tde documentation site_description: Documentation site_author: Percona LLC copyright: > - Percona LLC and/or its affiliates © 2023 — Cookie Consent + Percona LLC and/or its affiliates © 2025 — Cookie Consent repo_name: percona/pg_tde @@ -92,8 +92,8 @@ markdown_extensions: linenums: false - pymdownx.snippets: base_path: ["snippets"] - auto_append: - - services-banner.md +# auto_append: +# - services-banner.md - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg diff --git a/contrib/pg_tde/documentation/snippets/services-banner.md b/contrib/pg_tde/documentation/snippets/services-banner.md deleted file mode 100644 index 81886f96b9f..00000000000 --- a/contrib/pg_tde/documentation/snippets/services-banner.md +++ /dev/null @@ -1,13 +0,0 @@ -
- -## Get expert help { .title } - -If you need assistance, visit the community forum for comprehensive and free database knowledge, or contact our Percona Database Experts for professional support and services. - -
- -[:material-forum-outline: Community Forum](https://forums.percona.com/c/postgresql/pg-tde-transparent-data-encryption-tde/82) [:percona-logo: Get a Percona Expert](https://www.percona.com/about/contact) - - - -