|
| 1 | +# Design: encryption feature roadmap |
| 2 | + |
| 3 | +- Status: Proposed |
| 4 | +- Date: 2026-07-07 |
| 5 | +- Scope: candidate encryption features that `open_pg_tde` does not have today, |
| 6 | + with a rough assessment of value, effort, and fit with the current |
| 7 | + architecture. This is a planning document. It proposes no code. |
| 8 | + |
| 9 | +## What exists today |
| 10 | + |
| 11 | +For reference, the current feature surface: |
| 12 | + |
| 13 | +- **Data at rest**: `tde_heap` tables and their indexes and TOAST, encrypted |
| 14 | + through the storage manager. Ciphers: AES-128-CBC, AES-256-CBC, AES-128-XTS |
| 15 | + (selected per table via `open_pg_tde.data_cipher`, backed by a pluggable |
| 16 | + cipher registry). |
| 17 | +- **WAL**: full WAL encryption with AES-CTR (`open_pg_tde.wal_encrypt`). |
| 18 | +- **Keys**: two-tier hierarchy (principal key wraps per-relation internal |
| 19 | + keys). Providers: keyring file, KMIP, OpenBao. Per-database and global |
| 20 | + (server) providers. Manual principal key rotation. |
| 21 | +- **Controls**: `enforce_encryption`, `inherit_global_providers`. |
| 22 | + |
| 23 | +Known gaps that the documentation already calls out: temporary files and |
| 24 | +PostgreSQL statistics are not encrypted. |
| 25 | + |
| 26 | +## Candidate features |
| 27 | + |
| 28 | +Grouped by theme, with a priority tier. Tier 1 is high value and a natural fit |
| 29 | +with the current architecture; Tier 2 is high value but more effort; Tier 3 is |
| 30 | +large or needs a different architecture. |
| 31 | + |
| 32 | +### Data-at-rest coverage |
| 33 | + |
| 34 | +**1. Temporary file encryption (Tier 1).** |
| 35 | +Queries that exceed `work_mem` spill to temporary files in plaintext, and these |
| 36 | +can persist after a crash. This is a real data-at-rest leak and a documented |
| 37 | +limitation. A prototype already exists (a `BufFile` hook gated by an |
| 38 | +`encrypt_temp_files` GUC, wired to the same key hierarchy). Folding it in closes |
| 39 | +the most visible gap, so data files, WAL, and temp files all share one key |
| 40 | +hierarchy. Highest priority. |
| 41 | + |
| 42 | +**2. Statistics encryption (Tier 2).** |
| 43 | +`pg_statistic` stores sampled column values (most-common-values lists, histogram |
| 44 | +bounds) from encrypted tables in plaintext, so sensitive values can leak through |
| 45 | +the catalog. Encrypting or redacting statistics for encrypted relations closes |
| 46 | +this. Effort is moderate and the threat is concrete. |
| 47 | + |
| 48 | +**3. Tablespace-level encryption (Tier 1).** |
| 49 | +Encrypt an entire tablespace so relations created in it are encrypted |
| 50 | +automatically, instead of opting in per table. Covered by its own design doc |
| 51 | +(`tablespace-encryption.md`); the engine already keys on the relation file and |
| 52 | +tracks the tablespace OID, so this is mostly a policy layer. |
| 53 | + |
| 54 | +### Ciphers and cryptographic strength |
| 55 | + |
| 56 | +**4. AES-256-XTS for data files (Tier 1).** |
| 57 | +XTS is the recommended mode for storage encryption, but only AES-128-XTS is |
| 58 | +available today. AES-256-XTS is a small addition because the cipher registry is |
| 59 | +already pluggable; it is a new entry plus a GUC value, with no on-disk format |
| 60 | +change (the cipher id is recorded per relation). Low effort, clear value. |
| 61 | + |
| 62 | +**5. Authenticated page encryption, AES-GCM (Tier 2).** |
| 63 | +Data pages use CBC/XTS, which provide confidentiality but not integrity, so |
| 64 | +tampering with an encrypted page on disk is not detected. AES-GCM would add a |
| 65 | +per-page authentication tag and detect tampering. The internal keys are already |
| 66 | +wrapped with GCM, so the primitive is present, but per-page tags need space in |
| 67 | +the page layout, which is an on-disk format change and a larger effort. High |
| 68 | +value for tamper-evidence and compliance. |
| 69 | + |
| 70 | +**6. ChaCha20-Poly1305 (Tier 3).** |
| 71 | +An authenticated stream cipher that performs well on platforms without AES |
| 72 | +hardware acceleration. Low priority given AES-NI is common, but cheap to add to |
| 73 | +the registry if a use case appears. |
| 74 | + |
| 75 | +### Key management |
| 76 | + |
| 77 | +**7. Cloud KMS providers: AWS KMS, GCP KMS, Azure Key Vault (Tier 1).** |
| 78 | +Today external keys go through KMIP or OpenBao. Native integrations with the |
| 79 | +major cloud KMS services are a common requirement for managed deployments and |
| 80 | +extend the existing key-provider interface rather than changing the core. High |
| 81 | +commercial value. |
| 82 | + |
| 83 | +**8. Automatic principal key rotation (Tier 2).** |
| 84 | +Rotation is manual today. A scheduled or policy-driven rotation (interval or |
| 85 | +external trigger) that re-wraps internal keys under the new principal key, |
| 86 | +without downtime, is a standard compliance feature. The re-wrap machinery |
| 87 | +already exists for manual rotation. |
| 88 | + |
| 89 | +**9. HSM support via PKCS#11 (Tier 2).** |
| 90 | +Hold the principal key in a hardware security module and perform wrap/unwrap in |
| 91 | +the HSM. A key-provider addition, valuable for regulated environments. |
| 92 | + |
| 93 | +**10. Key-access audit logging (Tier 2).** |
| 94 | +Log every principal key access and unwrap (who, when, which key) for compliance |
| 95 | +and incident response. Fits alongside the key providers and is largely |
| 96 | +additive. |
| 97 | + |
| 98 | +### Granular and compliance features |
| 99 | + |
| 100 | +**11. Column-level encryption (Tier 3).** |
| 101 | +Encrypt specific columns rather than whole tables, protecting selected fields |
| 102 | +(for example PII) under a distinct threat model. This is a different |
| 103 | +architecture from the storage-manager approach (it needs type or expression |
| 104 | +level handling and query-path integration) and is a large effort, but it |
| 105 | +addresses a use case whole-relation encryption cannot. |
| 106 | + |
| 107 | +**12. FIPS 140-2/3 mode (Tier 3).** |
| 108 | +Run crypto through the OpenSSL FIPS provider and restrict to approved ciphers |
| 109 | +and key sizes, for deployments with a FIPS requirement. Mostly a build and |
| 110 | +policy effort on top of the existing OpenSSL usage. |
| 111 | + |
| 112 | +## Suggested sequencing |
| 113 | + |
| 114 | +1. **Temporary file encryption** and **AES-256-XTS**: both close known gaps, |
| 115 | + both are low effort, and both build directly on existing mechanisms. |
| 116 | +2. **Cloud KMS providers**: high demand, extends the provider interface. |
| 117 | +3. **Tablespace-level encryption**: per its own design doc. |
| 118 | +4. **Automatic key rotation** and **key-access audit logging**: compliance |
| 119 | + features on top of the existing key hierarchy. |
| 120 | +5. **Authenticated page encryption (AES-GCM)** and **statistics encryption**: |
| 121 | + higher-value hardening that involve format or catalog changes. |
| 122 | +6. **HSM/PKCS#11**, **FIPS mode**, and **column-level encryption**: larger or |
| 123 | + more specialized, scheduled by demand. |
| 124 | + |
| 125 | +## Notes |
| 126 | + |
| 127 | +- Anything touching the on-disk page format (AES-GCM tags) or the cipher set |
| 128 | + must preserve the ability to read data written by earlier versions, since the |
| 129 | + cipher id is recorded per relation and drives decryption. |
| 130 | +- New ciphers and providers should extend the existing registries rather than |
| 131 | + branch the core, to keep the maintenance burden of tracking the upstream |
| 132 | + patch low. |
| 133 | +- All C code must satisfy the |
| 134 | + [PostgreSQL coding conventions](https://www.postgresql.org/docs/current/source.html) |
| 135 | + per `CLAUDE.md`. |
0 commit comments