Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eql-text-equality-transcoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cipherstash/eql': minor
---

**Rust `TextEq` and `TextEqQuery` support Stack Encrypt's target-directed API behind the `stack-encrypt` feature.** The stored table and column identifier supplies the encryption context; native ciphertext and equality terms are transcoded into EQL payloads while Vitamin C owns plaintext encoding. This is a new producer profile with exact string equality, independent of existing cipherstash-client ciphertext and terms. Query operands carry no recoverable ciphertext.
32 changes: 32 additions & 0 deletions .github/workflows/test-eql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,18 @@ jobs:
github.event_name != 'pull_request'
|| needs.changes.outputs.relevant == 'true'
runs-on: blacksmith-16vcpu-ubuntu-2204
services:
encryption-postgres:
image: postgres:17
env:
POSTGRES_PASSWORD: postgres
ports:
- 7433:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
Expand Down Expand Up @@ -549,6 +561,26 @@ jobs:
rustup component add --toolchain "${active_rust_toolchain}" rustfmt clippy
mise run test:crates

# Registry builds require the unpublished Stack Encrypt crates from
# cipherstash-suite#2215 to be published before this change merges.
- name: Test Rust text equality with PostgreSQL
env:
PGPASSWORD: postgres
EQL_TEST_DATABASE_URL: "host=localhost port=7433 user=postgres password=postgres dbname=postgres"
run: |
set -euo pipefail
cargo test --locked -p eql-bindings --features stack-encrypt
cargo test --locked -p eql-encryption-tests
cargo clippy --locked -p eql-bindings -p eql-encryption-tests --all-features --all-targets -- -D warnings
psql -h localhost -p 7433 -U postgres -d postgres -v ON_ERROR_STOP=1 -f crates/eql-bindings/sql/cipherstash-encrypt.sql
cargo test --locked -p eql-encryption-tests --test text_eq -- --ignored

- name: Compile Rust text equality for WASI without HTTP
run: |
set -euo pipefail
rustup target add wasm32-wasip1
cargo check --locked -p eql-bindings --features stack-encrypt --target wasm32-wasip1

# Freshness gate for the eql-types codegen output: regenerate the
# TypeScript bindings and JSON Schemas and fail if the checked-in
# copies differ. Reuses the toolchain from the step above.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ If these variables are missing, tests that require live encryption will fail or
- `packages/utils`: Shared config (`utils/config`) and logger (`utils/logger`)
- `packages/bench`: Performance / index-engagement benchmarks (private, not published)
- `packages/protect-ffi`: Native FFI bindings to the CipherStash Client SDK (`@cipherstash/protect-ffi`) — the Rust core that `packages/stack` encrypts and decrypts through, absorbed from `cipherstash/protectjs-ffi`. Contains a **nested Cargo workspace** (`crates/`) and six per-platform binary packages under `platforms/*`, each published as `@cipherstash/protect-ffi-<platform>` and linked here via `workspace:*`. Also holds the repo's live FFI integration suite at `integration-tests/` — a private workspace member (`@cipherstash/ffi-integration-tests`) enrolled by its own literal entry in `pnpm-workspace.yaml`, needing Docker and credentials, and deliberately carrying **no `test` script** so `pnpm test` cannot reach it. See the "Working on protect-ffi" notes below before touching it — its default `test` and `build` are deliberately Rust-free.
- `packages/eql`: The Encrypt Query Language subtree — the SQL bundle that stores and queries encrypted payloads — absorbed from `cipherstash/encrypt-query-language`. **The directory is the subtree root, not the package.** It was imported at a *verbatim prefix* so its repo-root-relative paths (mise tasks, `Doxyfile`, `sync-generated.mjs`) keep resolving, which puts the npm package `@cipherstash/eql` two levels down at `packages/eql/packages/eql` — the same shape as `packages/protect-ffi/platforms/*`, and enrolled the same way, by an explicit `packages/eql/packages/*` glob in `pnpm-workspace.yaml`. The subtree root deliberately carries no `package.json`. Also contains a **nested Cargo workspace** at `packages/eql/crates/` (`eql-bindings`, published in lockstep with the npm package, plus `eql-domains` / `eql-codegen` / `eql-tests-macros`, which are not), a SQLx test crate at `packages/eql/tests/sqlx`, an ~900-line `mise.toml` task surface, its own `AGENTS.md`, and `docs/`. See the "Working on EQL" notes below before touching it.
- `packages/eql`: The Encrypt Query Language subtree — the SQL bundle that stores and queries encrypted payloads — absorbed from `cipherstash/encrypt-query-language`. **The directory is the subtree root, not the package.** It was imported at a *verbatim prefix* so its repo-root-relative paths (mise tasks, `Doxyfile`, `sync-generated.mjs`) keep resolving, which puts the npm package `@cipherstash/eql` two levels down at `packages/eql/packages/eql` — the same shape as `packages/protect-ffi/platforms/*`, and enrolled the same way, by an explicit `packages/eql/packages/*` glob in `pnpm-workspace.yaml`. The subtree root deliberately carries no `package.json`. Also contains a **nested Cargo workspace** at `packages/eql/crates/` (`eql-bindings`, published in lockstep with the npm package, plus `eql-domains` / `eql-codegen` / `eql-tests-macros`, which are not), a SQLx test crate at `packages/eql/tests/sqlx`, an unpublished encryption test crate at `packages/eql/tests/encryption` (real encryption with a fake key source, the executable Rustdoc example at `packages/eql/crates/eql-bindings/src/encryption/example.rs`, plus optional PostgreSQL coverage), an ~900-line `mise.toml` task surface, its own `AGENTS.md`, and `docs/`. See the "Working on EQL" notes below before touching it.
**Repository ownership:** EQL now lives in `cipherstash/stack`. File and update
EQL issues in this repository, never in the historical
`cipherstash/encrypt-query-language` repository. Old upstream issue and PR
Expand Down
6 changes: 6 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ This repository also carries the source of the **`eql-bindings`** Rust crate
lockstep with `@cipherstash/eql`. It is in scope for security reports on the
same terms as the npm packages above.

The `eql-encryption-tests` Rust crate (`packages/eql/tests/encryption`) is
an unpublished test harness for these bindings. It uses real encryption with
a fake key source, executes the Rustdoc text encryption example, and provides
optional disposable PostgreSQL coverage. It adds no published package or
production service.

> **Note on publishing.** `@cipherstash/eql` and the `eql-bindings` crate are
> developed here but are *published* from `cipherstash/encrypt-query-language`
> until the Phase 5 cutover in
Expand Down
Loading
Loading