Add Postgres TDE (pg_tde) encryption-at-rest guide#1033
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds Postgres TDE concept, deployment, operations, and backup/restore documentation, including Vault-backed configuration, encryption verification, key rotation, WAL encryption, and supporting Kubernetes manifests. ChangesPostgres TDE documentation
Estimated code review effort: 2 (Simple) | ~15 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/postgres/tde/guide/index.md`:
- Around line 190-195: Remove the `$` prompt prefixes from every command in the
terminal block near the Postgres TDE cleanup commands, while preserving the
commands and their order so the entire block can be copied and pasted directly.
In `@docs/guides/postgres/tde/overview/index.md`:
- Line 13: Replace the vague “here” link text with descriptive text explaining
that readers should start with the KubeDB documentation in
docs/guides/postgres/tde/overview/index.md lines 13-13 and
docs/guides/postgres/tde/guide/index.md lines 13-13, while preserving the
existing destination.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7efc4b2d-3e31-465f-8863-43cb35aa1ed3
📒 Files selected for processing (6)
docs/guides/postgres/tde/_index.mddocs/guides/postgres/tde/guide/index.mddocs/guides/postgres/tde/guide/yamls/enable-wal-encryption.yamldocs/guides/postgres/tde/guide/yamls/rotate-principal-key.yamldocs/guides/postgres/tde/guide/yamls/tde-postgres.yamldocs/guides/postgres/tde/overview/index.md
| ```bash | ||
| $ kubectl delete postgresopsrequest -n demo tde-rotate-key tde-enable-wal | ||
| $ kubectl delete pg -n demo tde-postgres | ||
| $ kubectl delete secret -n demo vault-token | ||
| $ kubectl delete ns demo | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove the $ prefix to improve copy-paste ergonomics.
When a code block contains a sequence of terminal commands without their output, omitting the $ prefix allows users to easily copy and paste the entire block at once (MD014).
💡 Proposed change
```bash
-$ kubectl delete postgresopsrequest -n demo tde-rotate-key tde-enable-wal
-$ kubectl delete pg -n demo tde-postgres
-$ kubectl delete secret -n demo vault-token
-$ kubectl delete ns demo
+kubectl delete postgresopsrequest -n demo tde-rotate-key tde-enable-wal
+kubectl delete pg -n demo tde-postgres
+kubectl delete secret -n demo vault-token
+kubectl delete ns demo</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 191-191: Dollar signs used before commands without showing output
(MD014, commands-show-output)
[warning] 192-192: Dollar signs used before commands without showing output
(MD014, commands-show-output)
[warning] 193-193: Dollar signs used before commands without showing output
(MD014, commands-show-output)
[warning] 194-194: Dollar signs used before commands without showing output
(MD014, commands-show-output)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/guides/postgres/tde/guide/index.md` around lines 190 - 195, Remove the
`$` prompt prefixes from every command in the terminal block near the Postgres
TDE cleanup commands, while preserving the commands and their order so the
entire block can be copied and pasted directly.
Source: Linters/SAST tools
|
Visit the preview URL for this PR (updated for commit 9ea86ed): https://kubedb-v2-hugo--pr1033-postgres-tde-rhzktlwd.web.app (expires Thu, 30 Jul 2026 17:58:40 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 0f29ae8ae0bd54a99bf2b223b6833be47acd5943 |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/guides/postgres/tde/guide/index.md (2)
49-53: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winRead the Vault token when creating the Secret.
--from-literal=token='<your-vault-token>'leaves the credential guidance in command text and can encourage users to pass the actual token tokubectl, exposing it in shell history and process listings. Create the Secret by reading the token from stdin or an environment variable instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/guides/postgres/tde/guide/index.md` around lines 49 - 53, Update the Secret creation example near the Vault token instructions to avoid placing the credential directly in the kubectl command; read the token from stdin or an environment variable while preserving the `token` key and `vault-token` Secret name.
105-108: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winResolve the current primary before running write commands.
docs/guides/postgres/tde/guide/yamls/tde-postgres.yamldeploystde-postgreswithreplicas: 3, sotde-postgres-0may be a replica after failover instead of a primary role selector. Use a documented primary selector, such as querying the KubeDB role/label, before running theCREATE TABLE/INSERTsteps to avoid read-only writes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/guides/postgres/tde/guide/index.md` around lines 105 - 108, Update the exec command in the TDE guide before the CREATE TABLE/INSERT steps to resolve the current tde-postgres primary using the documented KubeDB role or label selector instead of hardcoding tde-postgres-0. Ensure subsequent write commands target the resolved primary after failover.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/postgres/concepts/opsrequest.md`:
- Around line 179-182: Update the documentation text around
spec.rotatePrincipalKey to hyphenate the compound modifiers: change “per
relation internal keys” to “per-relation internal keys” and use “TDE-enabled
cluster” in the corresponding description. Preserve the existing meaning and
formatting.
In `@docs/guides/postgres/concepts/postgres.md`:
- Around line 280-282: Align the mutability documentation for spec.tde: in
docs/guides/postgres/concepts/postgres.md lines 280-282, identify
spec.tde.keyProvider and spec.tde.cipher as immutable while documenting the
operator-managed encryptWAL exception; in
docs/guides/postgres/concepts/opsrequest.md lines 192-195, state that users must
not patch spec.tde.encryptWAL directly and must use the EnableWALEncryption
OpsRequest as the supported mutation path.
In `@docs/guides/postgres/tde/backup/index.md`:
- Line 13: Update the introductory link in the documentation to replace the
vague “here” link text with a descriptive label identifying the KubeDB
documentation overview, while preserving the existing destination.
- Line 2: Update the user-facing wording throughout the TDE backup guide,
including the title and the referenced sections, to consistently use the
compound modifiers “TDE-encrypted,” “on-disk,” and “pg_tde-aware.”
- Around line 30-33: Update the KubeStash logical backup reference in the TDE
backup guide to accurately describe the workflow: name `pg_dump`/`pg_dumpall` as
backup tools and `psql` as the restore tool, replacing the incorrect
`pg_restore` reference while preserving the explanation that the normal protocol
is used and no extra TDE configuration is required.
- Around line 70-73: Add a brief prerequisite note before the
`spec.init.archiver.recoveryTimestamp` instruction stating that both encrypted
and unencrypted WAL TDE restores require the original principal key and its
KMS/provider configuration dependencies to be available for archive decryption.
- Around line 82-85: Qualify the imagePullSecrets guidance in the Postgres TDE
backup documentation: limit the shared-secret claim and “no per-resource
configuration needed” wording to KubeDB-managed backup/restore and archiver
Jobs, and separately document the required private-registry configuration for
Stash/KubeStash RestoreSession jobs, which do not inherit
Postgres.spec.podTemplate.spec.imagePullSecrets.
In `@docs/guides/postgres/tde/guide/index.md`:
- Around line 208-209: Update the backup and PITR sentence in the TDE guide to
hyphenate the compound modifier as “TDE-encrypted Postgres,” leaving the
surrounding link and wording unchanged.
---
Outside diff comments:
In `@docs/guides/postgres/tde/guide/index.md`:
- Around line 49-53: Update the Secret creation example near the Vault token
instructions to avoid placing the credential directly in the kubectl command;
read the token from stdin or an environment variable while preserving the
`token` key and `vault-token` Secret name.
- Around line 105-108: Update the exec command in the TDE guide before the
CREATE TABLE/INSERT steps to resolve the current tde-postgres primary using the
documented KubeDB role or label selector instead of hardcoding tde-postgres-0.
Ensure subsequent write commands target the resolved primary after failover.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 457ca845-128f-4873-a7ed-3dafd51bca69
📒 Files selected for processing (6)
docs/guides/postgres/concepts/catalog.mddocs/guides/postgres/concepts/opsrequest.mddocs/guides/postgres/concepts/postgres.mddocs/guides/postgres/tde/backup/index.mddocs/guides/postgres/tde/guide/index.mddocs/guides/postgres/tde/overview/index.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/guides/postgres/tde/overview/index.md
Fixes accessibility, copy-paste ergonomics, hyphenation, and factual accuracy issues raised on PR #1033: - Use descriptive link text instead of "here" for the intro doc link. - Drop the $ prompt prefix from the cleanup command block so it can be copied and run as-is. - Read the Vault token via a prompt instead of passing it inline to kubectl, so it never lands in shell history. - Resolve the current primary pod by its kubedb.com/role=primary label before exec'ing in, since it may not be tde-postgres-0 after a failover. - Correct the spec.tde mutability contract: only keyProvider and cipher are immutable; encryptWAL is mutable but should only be changed via the EnableWALEncryption OpsRequest. - Correct the KubeStash logical backup/restore tool names (pg_dump/ pg_dumpall for backup, psql for restore, not pg_restore). - Note that a TDE restore needs the original principal key resolvable through its key provider regardless of whether WAL encryption was on. - Clarify that KubeStash BackupConfiguration/RestoreSession Jobs don't inherit Postgres.spec.podTemplate.spec.imagePullSecrets and need their own jobTemplate configuration for private registries. - Hyphenate compound modifiers throughout (TDE-encrypted, per-relation, cluster-wide, two-tier, appliance-based, pre-existing, pg_tde-aware). Signed-off-by: Tamal Saha <tamal@appscode.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/postgres/tde/backup/index.md`:
- Around line 17-23: Update the opening paragraph of the TDE backup guide to
scope the limitation specifically to community physical backup and WAL-reading
paths, including pg_basebackup and continuous-archiving readers. Remove the
blanket claim covering all community backup/restore methods, and preserve the
logical-backup guidance using pg_dump, pg_dumpall, and psql.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 98184f26-2026-4412-a9be-000674fddb6d
📒 Files selected for processing (4)
docs/guides/postgres/concepts/opsrequest.mddocs/guides/postgres/tde/backup/index.mddocs/guides/postgres/tde/guide/index.mddocs/guides/postgres/tde/overview/index.md
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/guides/postgres/concepts/opsrequest.md
- docs/guides/postgres/tde/overview/index.md
- docs/guides/postgres/tde/guide/index.md
Document Transparent Data Encryption for Postgres via the Percona pg_tde extension: an overview (key hierarchy, providers, limitations, Percona version requirement) and a how-to guide (deploy a Vault-backed encrypted Postgres, verify with pg_tde_is_encrypted, rotate the principal key, and enable WAL encryption via PostgresOpsRequest), with sample YAMLs. Signed-off-by: Tamal Saha <tamal@appscode.com>
Add spec.tde to the Postgres CRD reference, spec.tde to the PostgresVersion reference, and the RotatePrincipalKey / EnableWALEncryption ops types (with their spec fields) to the PostgresOpsRequest reference. Signed-off-by: Tamal Saha <tamal@appscode.com>
Add a backup/restore page covering logical backup via KubeStash, physical backup/continuous archiving/PITR via the Percona-aware archiver image, and how to configure imagePullSecrets when the Percona TDE image is pulled from a private registry. Link it from the TDE overview and guide pages. Signed-off-by: Tamal Saha <tamal@appscode.com>
Fixes accessibility, copy-paste ergonomics, hyphenation, and factual accuracy issues raised on PR #1033: - Use descriptive link text instead of "here" for the intro doc link. - Drop the $ prompt prefix from the cleanup command block so it can be copied and run as-is. - Read the Vault token via a prompt instead of passing it inline to kubectl, so it never lands in shell history. - Resolve the current primary pod by its kubedb.com/role=primary label before exec'ing in, since it may not be tde-postgres-0 after a failover. - Correct the spec.tde mutability contract: only keyProvider and cipher are immutable; encryptWAL is mutable but should only be changed via the EnableWALEncryption OpsRequest. - Correct the KubeStash logical backup/restore tool names (pg_dump/ pg_dumpall for backup, psql for restore, not pg_restore). - Note that a TDE restore needs the original principal key resolvable through its key provider regardless of whether WAL encryption was on. - Clarify that KubeStash BackupConfiguration/RestoreSession Jobs don't inherit Postgres.spec.podTemplate.spec.imagePullSecrets and need their own jobTemplate configuration for private registries. - Hyphenate compound modifiers throughout (TDE-encrypted, per-relation, cluster-wide, two-tier, appliance-based, pre-existing, pg_tde-aware). Signed-off-by: Tamal Saha <tamal@appscode.com>
Signed-off-by: Tamal Saha <tamal@appscode.com>
The opening paragraph blanket-claimed TDE Postgres can't use the community backup/restore path, contradicting the logical-backup section below, which uses pg_dump/pg_dumpall and psql over the normal protocol without issue. Narrow the claim to the physical backup and WAL archiving path. Signed-off-by: Tamal Saha <tamal@appscode.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/postgres/tde/guide/index.md`:
- Around line 104-115: Update the TDE guide to capture the primary pod name
returned by the kubectl jsonpath lookup and reuse that variable for the
subsequent postgres kubectl exec and later WAL-check commands. Remove hardcoded
tde-postgres-0 references so all operations target the dynamically discovered
current primary after failover.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 969cf0ef-239b-4362-ba29-7f1ad4fac30f
📒 Files selected for processing (10)
docs/guides/postgres/concepts/catalog.mddocs/guides/postgres/concepts/opsrequest.mddocs/guides/postgres/concepts/postgres.mddocs/guides/postgres/tde/_index.mddocs/guides/postgres/tde/backup/index.mddocs/guides/postgres/tde/guide/index.mddocs/guides/postgres/tde/guide/yamls/enable-wal-encryption.yamldocs/guides/postgres/tde/guide/yamls/rotate-principal-key.yamldocs/guides/postgres/tde/guide/yamls/tde-postgres.yamldocs/guides/postgres/tde/overview/index.md
🚧 Files skipped from review as they are similar to previous changes (7)
- docs/guides/postgres/tde/_index.md
- docs/guides/postgres/tde/guide/yamls/tde-postgres.yaml
- docs/guides/postgres/tde/guide/yamls/rotate-principal-key.yaml
- docs/guides/postgres/concepts/catalog.md
- docs/guides/postgres/concepts/opsrequest.md
- docs/guides/postgres/tde/guide/yamls/enable-wal-encryption.yaml
- docs/guides/postgres/tde/overview/index.md
| Find the current primary pod (this cluster runs 3 replicas, so the primary may | ||
| not be `tde-postgres-0`, especially after a failover), then exec into it to | ||
| create a table and confirm it is encrypted: | ||
|
|
||
| ```bash | ||
| $ kubectl get pods -n demo --selector="app.kubernetes.io/instance=tde-postgres,kubedb.com/role=primary" -o jsonpath='{.items[0].metadata.name}' | ||
| tde-postgres-0 | ||
|
|
||
| $ kubectl exec -it -n demo tde-postgres-0 -c postgres -- bash | ||
|
|
||
| # inside the pod | ||
| $ psql |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reuse the dynamically discovered primary pod.
The guide correctly finds the current primary, but then hardcodes tde-postgres-0. After failover, the table-creation commands can run against a standby, and the later WAL check can target the wrong or unavailable pod.
Proposed fix
- $ kubectl get pods -n demo --selector="app.kubernetes.io/instance=tde-postgres,kubedb.com/role=primary" -o jsonpath='{.items[0].metadata.name}'
+ PRIMARY_POD=$(kubectl get pods -n demo --selector="app.kubernetes.io/instance=tde-postgres,kubedb.com/role=primary" -o jsonpath='{.items[0].metadata.name}')
+ echo "$PRIMARY_POD"
- $ kubectl exec -it -n demo tde-postgres-0 -c postgres -- bash
+ kubectl exec -it -n demo "$PRIMARY_POD" -c postgres -- bash
- $ kubectl exec -n demo tde-postgres-0 -c postgres -- psql -Atqc "SHOW pg_tde.wal_encrypt;"
+ kubectl exec -n demo "$PRIMARY_POD" -c postgres -- psql -Atqc "SHOW pg_tde.wal_encrypt;"Also applies to: 189-190
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/guides/postgres/tde/guide/index.md` around lines 104 - 115, Update the
TDE guide to capture the primary pod name returned by the kubectl jsonpath
lookup and reuse that variable for the subsequent postgres kubectl exec and
later WAL-check commands. Remove hardcoded tde-postgres-0 references so all
operations target the dynamically discovered current primary after failover.
Adds user documentation for Postgres Transparent Data Encryption (encryption at rest) via the Percona pg_tde extension, under
docs/guides/postgres/tde/.Contents
USING tde_heap,SET ACCESS METHOD,defaultEncryptedTables), and limitations (Percona 17.x only, what is not encrypted, Citus/TimescaleDB incompatibility, not retroactive).pg_tde_is_encrypted, rotate the principal key (RotatePrincipalKeyops), and enable WAL encryption (EnableWALEncryptionops), with sample YAMLs.Documents the feature implemented in kubedb/apimachinery#1831 and the related operator, init-image, coordinator and installer PRs. Placed at weight 75, right after the TLS/SSL (in-transit) guide.
Summary by CodeRabbit
pg_tdeconcepts, key hierarchy, encryption behavior, and limitations/coverage gaps.spec.tdeconfiguration details and immutability/admission notes.RotatePrincipalKey/EnableWALEncryptionoperations.