Repository navigation
EQL v3 JSON: implement JSONPath selector-with-constraint querying (->, ->>) #623
Copy link
Copy link
Closed
Description
Activity
- added a commit that references this issue
on Jul 12, 2026 Additional design note surfaced in #621: the typed client shares one plaintext type (
PlaintextForColumn<Col>) betweenencryptandencryptQuery. For ajsoncolumn that's nowJsonDocument(object/array/null). But a selector query needs a top-level string needle ('$.user.email'), whichJsonDocumentexcludes. So selector support needsencryptQuery's json plaintext to differ fromencrypt's (document for containment | string for selector) — encrypt must still reject a bare scalar. Factor that into the typing when implementing.- added a commit that references this issue
on Jul 14, 2026 - added 4 commits that reference this issue
on Jul 15, 2026 Shipped in #651 (merged 2026-07-15). Everything in the proposed change landed:
- Selector querying on
types.Jsoncolumns viaops.selector(col, '$.path')returningeq/ne/gt/gte/lt/lte, emitted aseql_v3.jsonb_path_query_first(col, <selector>)compared against an encrypted operand — socol->'bar' = $1andcol->'wee' > $1work end-to-end. Paths are validated (no wildcards/array steps, prototype-polluting segments rejected), scalar-leaf capability is guarded, andneincludes absent-path rows (OR ... IS NULL) by documented design. - Live oracle + tests:
selector.test.ts(unit),json-selector.integration.test.ts(real Postgres + real crypto, including an absent-path row), plus type tests — and the CI gap that had left stack-drizzle/stack-supabasetest:typesunwired got fixed along the way. - Skills: the pattern is documented in
stash-encryptionandstash-drizzle, including the ciphertext-in-WHERE disclosure.
Not closed by this issue, tracked separately:
- Supabase selector querying → EQL v3 JSON on Supabase: encrypted containment + JSONPath selector querying #650 (per the scope decision to land Drizzle first).
- Ciphertext-free RHS: the operand currently uses the storage payload because
encryptQuerycan't mint an ordering (op) JSON needle → EQL v3 ste_vec: encryptQuery can't mint an ordering (op) JSON query needle for selector-with-constraint protectjs-ffi#137; the operator layer already isolates the swap.
- Selector querying on
Metadata
Metadata
Assignees
Labels
No labels
Context
#621 adds EQL v3 encrypted JSON (
types.Json) with containment querying only —ops.contains(col, subObject)emitting the@>operator with aquery_jsonbneedle.EQL v3 supports a second JSON query form that #621 does not implement: JSONPath selector with a constraint, e.g.
The
eql_v3_jsondomain ships the operators for it —->(text|int) and->>(text|int) — andencryptQuery(value, { queryType: 'searchableJson' })already auto-infers a selector term for string (JSONPath) needles. What's missing is the adapter surface: the v3 Drizzle operators expose no->/->>selector, so a selector-with-constraint query can't be expressed, and there are no tests for it.Proposed change
->/->>) to the v3 Drizzle integration fortypes.Jsoncolumns.col->'bar' = $1/col->'wee' > $1work end-to-end.json-contains.integration.test.ts).skills/stash-encryption/skills/stash-drizzle.Notes
https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w