Skip to content

Commit 36480c3

Browse files
calvinbrewerfreshtonic
authored andcommitted
feat: upgrade to eql 2.3.1
1 parent ba36f0b commit 36480c3

7 files changed

Lines changed: 70 additions & 34 deletions

File tree

.changeset/protect-ffi-0-22-0.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
"stash": minor
88
---
99

10-
Upgrade `@cipherstash/protect-ffi` to `0.22.0` and the bundled CipherStash EQL extension to `eql-2.3.0`.
10+
Upgrade `@cipherstash/protect-ffi` to `0.22.0` and the bundled CipherStash EQL extension to `eql-2.3.1`.
1111

1212
Breaking upstream changes adopted in this release:
1313

1414
- **Encrypt-config schema version**: `buildEncryptConfig` now emits `{ v: 1, ... }` (was `{ v: 2, ... }`). protect-ffi `0.22.0` validates this field and rejects any value other than `1` with the new `UNSUPPORTED_CONFIG_VERSION` error code.
1515
- **SteVec encoding default flipped**: protect-ffi's default `mode` for `ste_vec` indexes changed from `compat` to `standard`. The two encodings are not cross-compatible. Existing JSON-searchable data that was indexed under `compat` will need to be re-encrypted to be queryable. The stack adopts the new `standard` default — there is no longer a way to pin `compat` from the SDK.
16-
- **EQL extension bumped to `eql-2.3.0`**: the new SteVec `standard` encoding requires matching support in the database EQL extension. The CLI's bundled SQL (`packages/cli/src/sql/*.sql`) and the `@cipherstash/prisma-next` install bundle (`migrations/20260601T0000_install_eql_bundle/ops.json` + `eql-install.generated.ts`) are updated to `eql-2.3.0`. Databases installed with an older EQL extension must be reinstalled (`stash db install`) before containment / contained-by queries against SteVec columns will work.
16+
- **EQL extension bumped to `eql-2.3.1`**: the new SteVec `standard` encoding requires matching support in the database EQL extension. The CLI's bundled SQL (`packages/cli/src/sql/*.sql`) and the `@cipherstash/prisma-next` install bundle (`migrations/20260601T0000_install_eql_bundle/ops.json` + `eql-install.generated.ts`) are updated to `eql-2.3.1`. Databases installed with an older EQL extension must be reinstalled (`stash db install`) before containment / contained-by queries against SteVec columns will work. `eql-2.3.1` ships the `_encrypted_check_c` fix for SteVec storage payloads ([cipherstash/encrypt-query-language#232](https://github.com/cipherstash/encrypt-query-language/issues/232)).
1717
- **New error codes**: `ProtectErrorCode` (re-exported from `@cipherstash/protect-ffi`) gains `MATCH_REQUIRES_TEXT` and `UNSUPPORTED_CONFIG_VERSION`. Exhaustive switches over `ProtectErrorCode` will need additional cases.
1818
- **`match` index validation**: protect-ffi now rejects `match` indexes on columns whose `cast_as` is not text-family (`'text'` / `'string'`) with `MATCH_REQUIRES_TEXT`. The stack's `freeTextSearch()` builder is unaffected because it only targets string-typed columns.
1919
- **`Encrypted` ciphertext shape**: protect-ffi's `Encrypted` type is now a discriminated union keyed on `k` (`'ct'` for scalars, `'sv'` for SteVec). SteVec storage payloads now place the root document ciphertext at `sv[0].c`. The stack's `isEncryptedPayload` runtime check continues to work because storage payloads still carry `c` (scalar) or `sv` (SteVec). The DynamoDB helpers (`toEncryptedDynamoItem`, `SearchTermsOperation`) now narrow on `k` before reading variant-only fields.

packages/cli/src/sql/cipherstash-encrypt-no-operator-family.sql

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,7 +2915,7 @@ CREATE FUNCTION eql_v2.version()
29152915
RETURNS text
29162916
IMMUTABLE STRICT PARALLEL SAFE
29172917
AS $$
2918-
SELECT 'eql-2.3.0';
2918+
SELECT 'eql-2.3.1';
29192919
$$ LANGUAGE SQL;
29202920

29212921

@@ -6221,12 +6221,21 @@ $$ LANGUAGE plpgsql;
62216221
--! @brief Validate ciphertext field in encrypted payload
62226222
--! @internal
62236223
--!
6224-
--! Checks that the encrypted payload contains the required 'c' (ciphertext) field
6225-
--! which stores the encrypted data.
6224+
--! Checks that the encrypted payload carries the required root-level ciphertext
6225+
--! envelope. The v2.3 payload schema admits two mutually exclusive top-level
6226+
--! shapes (`docs/reference/schema/eql-payload-v2.3.schema.json`):
6227+
--!
6228+
--! - `EncryptedPayload` (scalar) — carries `c` at the root.
6229+
--! - `SteVecPayload` (jsonb / structured) — carries `sv` at the root; the
6230+
--! root document ciphertext lives inside `sv[0].c`, so `c` is absent at
6231+
--! the root.
6232+
--!
6233+
--! Either shape satisfies this check. Per-element ciphertext validity on
6234+
--! `sv` entries is enforced separately by the `eql_v2.ste_vec_entry` DOMAIN.
62266235
--!
62276236
--! @param jsonb Encrypted payload to validate
6228-
--! @return Boolean True if 'c' field is present
6229-
--! @throws Exception if 'c' field is missing
6237+
--! @return Boolean True if either 'c' or 'sv' is present at the root
6238+
--! @throws Exception if neither 'c' nor 'sv' is present
62306239
--!
62316240
--! @note Used in CHECK constraints to ensure payload structure
62326241
--! @see eql_v2.check_encrypted
@@ -6235,10 +6244,10 @@ CREATE FUNCTION eql_v2._encrypted_check_c(val jsonb)
62356244
SET search_path = pg_catalog, extensions, public
62366245
AS $$
62376246
BEGIN
6238-
IF (val ? 'c') THEN
6247+
IF (val ? 'c') OR (val ? 'sv') THEN
62396248
RETURN true;
62406249
END IF;
6241-
RAISE 'Encrypted column missing ciphertext (c) field: %', val;
6250+
RAISE 'Encrypted column missing ciphertext (c) or ste_vec (sv) field: %', val;
62426251
END;
62436252
$$ LANGUAGE plpgsql;
62446253

packages/cli/src/sql/cipherstash-encrypt-supabase.sql

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,7 +2915,7 @@ CREATE FUNCTION eql_v2.version()
29152915
RETURNS text
29162916
IMMUTABLE STRICT PARALLEL SAFE
29172917
AS $$
2918-
SELECT 'eql-2.3.0';
2918+
SELECT 'eql-2.3.1';
29192919
$$ LANGUAGE SQL;
29202920

29212921

@@ -6221,12 +6221,21 @@ $$ LANGUAGE plpgsql;
62216221
--! @brief Validate ciphertext field in encrypted payload
62226222
--! @internal
62236223
--!
6224-
--! Checks that the encrypted payload contains the required 'c' (ciphertext) field
6225-
--! which stores the encrypted data.
6224+
--! Checks that the encrypted payload carries the required root-level ciphertext
6225+
--! envelope. The v2.3 payload schema admits two mutually exclusive top-level
6226+
--! shapes (`docs/reference/schema/eql-payload-v2.3.schema.json`):
6227+
--!
6228+
--! - `EncryptedPayload` (scalar) — carries `c` at the root.
6229+
--! - `SteVecPayload` (jsonb / structured) — carries `sv` at the root; the
6230+
--! root document ciphertext lives inside `sv[0].c`, so `c` is absent at
6231+
--! the root.
6232+
--!
6233+
--! Either shape satisfies this check. Per-element ciphertext validity on
6234+
--! `sv` entries is enforced separately by the `eql_v2.ste_vec_entry` DOMAIN.
62266235
--!
62276236
--! @param jsonb Encrypted payload to validate
6228-
--! @return Boolean True if 'c' field is present
6229-
--! @throws Exception if 'c' field is missing
6237+
--! @return Boolean True if either 'c' or 'sv' is present at the root
6238+
--! @throws Exception if neither 'c' nor 'sv' is present
62306239
--!
62316240
--! @note Used in CHECK constraints to ensure payload structure
62326241
--! @see eql_v2.check_encrypted
@@ -6235,10 +6244,10 @@ CREATE FUNCTION eql_v2._encrypted_check_c(val jsonb)
62356244
SET search_path = pg_catalog, extensions, public
62366245
AS $$
62376246
BEGIN
6238-
IF (val ? 'c') THEN
6247+
IF (val ? 'c') OR (val ? 'sv') THEN
62396248
RETURN true;
62406249
END IF;
6241-
RAISE 'Encrypted column missing ciphertext (c) field: %', val;
6250+
RAISE 'Encrypted column missing ciphertext (c) or ste_vec (sv) field: %', val;
62426251
END;
62436252
$$ LANGUAGE plpgsql;
62446253

packages/cli/src/sql/cipherstash-encrypt.sql

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,7 +3843,7 @@ CREATE FUNCTION eql_v2.version()
38433843
RETURNS text
38443844
IMMUTABLE STRICT PARALLEL SAFE
38453845
AS $$
3846-
SELECT 'eql-2.3.0';
3846+
SELECT 'eql-2.3.1';
38473847
$$ LANGUAGE SQL;
38483848

38493849

@@ -6460,12 +6460,21 @@ $$ LANGUAGE plpgsql;
64606460
--! @brief Validate ciphertext field in encrypted payload
64616461
--! @internal
64626462
--!
6463-
--! Checks that the encrypted payload contains the required 'c' (ciphertext) field
6464-
--! which stores the encrypted data.
6463+
--! Checks that the encrypted payload carries the required root-level ciphertext
6464+
--! envelope. The v2.3 payload schema admits two mutually exclusive top-level
6465+
--! shapes (`docs/reference/schema/eql-payload-v2.3.schema.json`):
6466+
--!
6467+
--! - `EncryptedPayload` (scalar) — carries `c` at the root.
6468+
--! - `SteVecPayload` (jsonb / structured) — carries `sv` at the root; the
6469+
--! root document ciphertext lives inside `sv[0].c`, so `c` is absent at
6470+
--! the root.
6471+
--!
6472+
--! Either shape satisfies this check. Per-element ciphertext validity on
6473+
--! `sv` entries is enforced separately by the `eql_v2.ste_vec_entry` DOMAIN.
64656474
--!
64666475
--! @param jsonb Encrypted payload to validate
6467-
--! @return Boolean True if 'c' field is present
6468-
--! @throws Exception if 'c' field is missing
6476+
--! @return Boolean True if either 'c' or 'sv' is present at the root
6477+
--! @throws Exception if neither 'c' nor 'sv' is present
64696478
--!
64706479
--! @note Used in CHECK constraints to ensure payload structure
64716480
--! @see eql_v2.check_encrypted
@@ -6474,10 +6483,10 @@ CREATE FUNCTION eql_v2._encrypted_check_c(val jsonb)
64746483
SET search_path = pg_catalog, extensions, public
64756484
AS $$
64766485
BEGIN
6477-
IF (val ? 'c') THEN
6486+
IF (val ? 'c') OR (val ? 'sv') THEN
64786487
RETURN true;
64796488
END IF;
6480-
RAISE 'Encrypted column missing ciphertext (c) field: %', val;
6489+
RAISE 'Encrypted column missing ciphertext (c) or ste_vec (sv) field: %', val;
64816490
END;
64826491
$$ LANGUAGE plpgsql;
64836492

packages/prisma-next/migrations/20260601T0000_install_eql_bundle/ops.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/prisma-next/src/migration/eql-bundle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Vendored CipherStash EQL bundle SQL.
33
*
44
* The CipherStash team ships the bundle as a single Postgres script
5-
* (~5,750 lines, currently `eql-2.2.1`) that creates the `eql_v2`
5+
* (~7,650 lines, currently `eql-2.3.1`) that creates the `eql_v2`
66
* schema, the `eql_v2_*` composite types / domains, the
77
* `eql_v2_configuration` table, plus roughly 169 functions, 46
88
* operators, 4 casts, and 9 operator classes / families. CipherStash

packages/prisma-next/src/migration/eql-install.generated.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// @generated — DO NOT EDIT.
22
// Source: scripts/vendor-eql-install.ts
3-
// Bundle pinned version: eql-2.3.0
3+
// Bundle pinned version: eql-2.3.1
44
//
55
// This file is committed to source control so dev environments and
66
// offline builds work without network access. Regenerate with
77
// `pnpm vendor-eql-install` after bumping EQL_VERSION in the script.
88

9-
export const EQL_INSTALL_VERSION = 'eql-2.3.0' as const;
9+
export const EQL_INSTALL_VERSION = 'eql-2.3.1' as const;
1010

1111
export const EQL_INSTALL_SQL: string = `--! @file schema.sql
1212
--! @brief EQL v2 schema creation
@@ -3853,7 +3853,7 @@ CREATE FUNCTION eql_v2.version()
38533853
RETURNS text
38543854
IMMUTABLE STRICT PARALLEL SAFE
38553855
AS $$
3856-
SELECT 'eql-2.3.0';
3856+
SELECT 'eql-2.3.1';
38573857
$$ LANGUAGE SQL;
38583858
38593859
@@ -6470,12 +6470,21 @@ $$ LANGUAGE plpgsql;
64706470
--! @brief Validate ciphertext field in encrypted payload
64716471
--! @internal
64726472
--!
6473-
--! Checks that the encrypted payload contains the required 'c' (ciphertext) field
6474-
--! which stores the encrypted data.
6473+
--! Checks that the encrypted payload carries the required root-level ciphertext
6474+
--! envelope. The v2.3 payload schema admits two mutually exclusive top-level
6475+
--! shapes (\`docs/reference/schema/eql-payload-v2.3.schema.json\`):
6476+
--!
6477+
--! - \`EncryptedPayload\` (scalar) — carries \`c\` at the root.
6478+
--! - \`SteVecPayload\` (jsonb / structured) — carries \`sv\` at the root; the
6479+
--! root document ciphertext lives inside \`sv[0].c\`, so \`c\` is absent at
6480+
--! the root.
6481+
--!
6482+
--! Either shape satisfies this check. Per-element ciphertext validity on
6483+
--! \`sv\` entries is enforced separately by the \`eql_v2.ste_vec_entry\` DOMAIN.
64756484
--!
64766485
--! @param jsonb Encrypted payload to validate
6477-
--! @return Boolean True if 'c' field is present
6478-
--! @throws Exception if 'c' field is missing
6486+
--! @return Boolean True if either 'c' or 'sv' is present at the root
6487+
--! @throws Exception if neither 'c' nor 'sv' is present
64796488
--!
64806489
--! @note Used in CHECK constraints to ensure payload structure
64816490
--! @see eql_v2.check_encrypted
@@ -6484,10 +6493,10 @@ CREATE FUNCTION eql_v2._encrypted_check_c(val jsonb)
64846493
SET search_path = pg_catalog, extensions, public
64856494
AS $$
64866495
BEGIN
6487-
IF (val ? 'c') THEN
6496+
IF (val ? 'c') OR (val ? 'sv') THEN
64886497
RETURN true;
64896498
END IF;
6490-
RAISE 'Encrypted column missing ciphertext (c) field: %', val;
6499+
RAISE 'Encrypted column missing ciphertext (c) or ste_vec (sv) field: %', val;
64916500
END;
64926501
$$ LANGUAGE plpgsql;
64936502

0 commit comments

Comments
 (0)