Skip to content

Commit 2cb292d

Browse files
OffgridwithJDclaude
andcommitted
docs: add encryption feature roadmap
Add a planning document that evaluates encryption features open_pg_tde does not have today, with value/effort/fit and a suggested sequencing. Tier 1 (natural fit, high value): temporary file encryption, AES-256-XTS, cloud KMS providers (AWS/GCP/Azure), tablespace-level encryption. Tier 2: statistics encryption, authenticated page encryption (AES-GCM), automatic key rotation, HSM/PKCS#11, key-access audit logging. Tier 3: column-level encryption, FIPS mode, ChaCha20-Poly1305. No implementation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3b79c3e commit 2cb292d

2 files changed

Lines changed: 136 additions & 0 deletions

File tree

docs/design/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ a date.
99

1010
| Document | Status |
1111
| -------- | ------ |
12+
| [Encryption feature roadmap](encryption-roadmap.md) | Proposed |
1213
| [Tablespace-level encryption](tablespace-encryption.md) | Proposed |

docs/design/encryption-roadmap.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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

Comments
 (0)