Skip to content

Commit 9bcec22

Browse files
committed
fix(v3): resolve column domains when the client is built, not per row
Every encrypted row re-derived its column's eql_v3 domain name and re-scanned the eql-bindings domain inventory. Resolve every configured column once, when the client is built, and hand the encrypt seams the resolved target. Resolving up front also makes an unrepresentable column a configuration error rather than a per-row one: it now fails newClient, naming the offending table.column, instead of on the first encrypt to it — which left a configured-but-never-written column silently broken. This is deliberately fatal to the whole client, so it is a BREAKING change for a v3 config containing such a column that the app only decrypts or never touches: that client built before and does not now. CHANGELOG carries the note and the remedy (read-only services can build with eqlVersion 2 — decrypt is version-agnostic and reads v3 payloads regardless). ResolvedEncryptConfig owns the whole fail-fast sequence (validate eqlVersion, parse the config, resolve each column) so the Neon and wasm clients cannot drift: both now hold one Arc and share the sequence rather than hand-assembling the same three fields behind identical resolver() methods. Each column's config and target live in one entry, so resolve() serves both from a single lookup and no second map's keys can disagree with the first. Config parsing now runs after the auth strategy is built, before any network I/O — the strategy is built first on both targets, so a broken strategy reports the same way on each. Config errors now precede auth/network errors for all clients, both wire versions. - errors name table.column: a whole-config sweep has no encrypt(table, column) call site to disambiguate the bare name, and two tables may configure the same column - encrypt_bulk carries the Copy OutputTarget out of its first loop on both targets, as encrypt_query_bulk already did, dropping a per-row re-lookup and an unreachable error arm after rows were encrypted - the conversion tests resolve through ResolvedEncryptConfig itself rather than a hand-rolled match their doc claimed was the real seam - new tests: the resolved target's variant and domain (nothing asserted either), unknown-column, table disambiguation, and the wasm build's rejection wiring, which no test reached
1 parent d21a87a commit 9bcec22

6 files changed

Lines changed: 561 additions & 214 deletions

File tree

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,40 @@ uses the promoted section as the GitHub release notes.
1515

1616
## [Unreleased]
1717

18+
### Breaking
19+
20+
- **An `eqlVersion: 3` client no longer builds when ANY configured column is
21+
one EQL v3 cannot represent** — even a column you only decrypt, query by
22+
selector, or never touch. `newClient` now maps every configured column onto
23+
its `eql_v3` domain up front, so such a config throws
24+
`EQL_V3_UNSUPPORTED_COLUMN` there — naming the offending `table.column`
25+
instead of on the first `encrypt` to it.
26+
27+
Previously the client built and only writes to that column failed, so a
28+
configured-but-never-written column never errored at all. A config declaring
29+
a column v3 cannot store is a configuration error, and this reports it as
30+
one: at build, once, naming the column and a remedy, rather than on a write
31+
that may not happen until production.
32+
33+
**If this rejects a config that worked before**, either drop the offending
34+
column's indexes (the error names which, and why), or — for a service that
35+
only reads — build with `eqlVersion: 2`: decrypt is version-agnostic and
36+
reads v3 payloads regardless of the client's setting. v2 clients are
37+
unaffected by this check: their payloads pass through unconverted and need
38+
no domain.
39+
40+
### Changed
41+
42+
- **`eqlVersion: 3` column domains are resolved once, when the client is
43+
built**, rather than per encrypted row. Every row used to re-derive the
44+
domain name and re-scan the eql-bindings domain inventory; that work now
45+
happens once per client.
46+
- **`newClient` now parses `encryptConfig` before contacting ZeroKMS** (all
47+
clients, both wire versions). A malformed config previously surfaced only
48+
after auth and a network round-trip; it now fails fast with no I/O. Where
49+
credentials *and* the config are both bad, the config error is the one you
50+
see — previously it was the auth error.
51+
1852
## [0.29.0] - 2026-07-09
1953

2054
### Added

0 commit comments

Comments
 (0)