diff --git a/ANNOUNCEMENT.md b/ANNOUNCEMENT.md new file mode 100644 index 00000000..854cd8f1 --- /dev/null +++ b/ANNOUNCEMENT.md @@ -0,0 +1,54 @@ +# CipherStash Proxy 3.1.0 + +CipherStash Proxy 3.1.0 makes Proxy safer behind connection poolers, closes several paths by which plaintext could reach PostgreSQL, and adds command-line flags for connecting to the database and requiring TLS. + +This release refuses some statements that earlier versions forwarded, so read [Before you upgrade](#before-you-upgrade) first. +The full list of changes is in the [CHANGELOG](https://github.com/cipherstash/proxy/blob/main/CHANGELOG.md#310---2026-11-04). + +## Before you upgrade + +Most of these changes refuse something that 3.0 accepted, and the rest change how Proxy behaves. +Check that your applications and drivers do not rely on the old behaviour. + +- **Reserved EQL payload shapes**: on encrypted columns, JSON objects shaped like EQL storage or query payloads are now validated as EQL instead of being encrypted as plaintext, with no opt-out. Audit plaintext writes for these key combinations; [Invalid encrypted value](https://github.com/cipherstash/proxy/blob/main/docs/errors.md#encrypt-invalid-inbound-eql-payload) includes a `jsonb` scan predicate. +- **Settings commands Proxy cannot honour**: a simple query that changes a `CIPHERSTASH.*` setting and then needs encryption, unknown `CIPHERSTASH.*` setting names or values, `SET ALL`, and prepared statements made stale by a settings change are refused. +- **`SET LOCAL CIPHERSTASH.*`** now ends with the transaction instead of lasting for the connection. Use `SET` where a keyset must persist after `COMMIT`. +- **SQL `PREPARE` bound through the extended protocol** is refused with PostgreSQL's `26000` error. Prepare with Parse, or run with SQL `EXECUTE`. +- **Writes Proxy cannot resolve or type check** are refused while encrypted columns are configured, including `MERGE`, SQL `PREPARE` of a write, writes to views, foreign tables and schemas outside the loaded search path, and some bulk `UPDATE` and `INSERT` forms. +- **Reads an encrypted column cannot support** are refused, including a comparison such as `<` on a column with no ordering index, and `ORDER BY`, `GROUP BY`, `DISTINCT` or `UNION` over a column without the ordering or equality index they need. +- **`COPY ... FROM` into encrypted columns** is refused. Load those columns with `INSERT`. +- **Default keyset**: when a connection selects no keyset, Proxy now uses `CS_DEFAULT_KEYSET_ID` rather than the account default. Verify the two are intended; values written under an unintended account default must be re-encrypted. +- **`require_tls` without a certificate** now fails at startup. Configure TLS, or unset `CS_SERVER__REQUIRE_TLS`. +- **Building from source** requires Rust 1.89.0 or later. + +The floating `cipherstash/proxy:3.0` Docker tag does not move to this release, but `cipherstash/proxy:latest` does. +If you run `latest`, pin `cipherstash/proxy:3.0` until you have made these checks. +Pin `cipherstash/proxy:3.1` or `cipherstash/proxy:3.1.0` once you are ready. + +## Highlights + +### Safer behind connection poolers + +`DISCARD ALL` and `RESET ALL` now return Proxy's per-connection keyset and mapping settings to their startup values, so a session-mode pooler no longer hands one client's keyset to the next. +`SET LOCAL CIPHERSTASH.KEYSET_ID`, `KEYSET_NAME` and `UNSAFE_DISABLE_MAPPING` give a setting that lasts for one transaction, which is the safe way to select a tenant's keyset behind a transaction-mode pooler. +[Connection poolers](https://github.com/cipherstash/proxy/blob/main/docs/reference/connection-poolers.md) documents which PgBouncer and PgCat versions and pool modes work with Proxy. + +### Fewer paths for plaintext to reach PostgreSQL + +Proxy now refuses writes it cannot type check, `COPY` into encrypted columns, and statements whose encryption results come back short, where it previously forwarded them as written. +Statements after `COPY ... FROM STDIN` in a simple query are now checked and encrypted like any other. + +### Application-generated EQL values + +Applications can send EQL v3 storage payloads and query operands they produced themselves. +Proxy authenticates each ciphertext, checks it names the destination column, and re-derives its search terms before forwarding it. + +### New command-line flags + +`--database-url` sets the database connection from one PostgreSQL connection string, and `--db-port` and `--db-password` join the existing `--db-*` flags. +`--tls` requires TLS from clients, and `--no-tls` forces a plaintext listener. +Run in a terminal, Proxy is now quiet by default and prints its listen address; pass `--debug` for debug logging. + +### Fixes + +This release also fixes query cancellation through Proxy, memory growth on long-lived connections that deallocate with SQL, schema-qualified table names, and the `--db-user` flag, which previously had no effect. diff --git a/CHANGELOG.md b/CHANGELOG.md index 37c446dd..f8f77e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +## [3.1.0] - 2026-11-04 + ### Added - **Connection flags**: `--database-url` sets the database host, port, user, password and name from one PostgreSQL connection string, and `--db-port` (`-P`) and `--db-password` (`-W`) join the existing `--db-*` flags, which override matching parts of the URL. A URL sets only the parts it contains. Connection strings with any other option, such as `sslmode`, or with a Unix socket host or multiple hosts, are rejected, because Proxy cannot apply them. A password on the command line is exposed in shell history and the process list, so prefer `CS_DATABASE__PASSWORD`. @@ -454,7 +456,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - Integration with CipherStash ZeroKMS. - Encrypt Query Language (EQL) for indexing and searching encrypted data. -[Unreleased]: https://github.com/cipherstash/proxy/compare/v3.0.1...HEAD +[Unreleased]: https://github.com/cipherstash/proxy/compare/v3.1.0...HEAD +[3.1.0]: https://github.com/cipherstash/proxy/compare/v3.0.1...v3.1.0 [3.0.1]: https://github.com/cipherstash/proxy/compare/v3.0.0...v3.0.1 [3.0.0]: https://github.com/cipherstash/proxy/compare/v2.2.4...v3.0.0 [2.2.4]: https://github.com/cipherstash/proxy/compare/v2.2.3...v2.2.4 diff --git a/Cargo.lock b/Cargo.lock index b1cbaf2f..40fae3fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -839,7 +839,7 @@ dependencies = [ [[package]] name = "cipherstash-proxy" -version = "3.0.1" +version = "3.1.0" dependencies = [ "arc-swap", "async-trait", @@ -1633,7 +1633,7 @@ dependencies = [ [[package]] name = "eql-mapper-macros" -version = "3.0.1" +version = "3.1.0" dependencies = [ "pretty_assertions", "proc-macro2", @@ -4468,7 +4468,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "showcase" -version = "3.0.1" +version = "3.1.0" dependencies = [ "cipherstash-client", "cipherstash-config", diff --git a/Cargo.toml b/Cargo.toml index 91d8d148..74664968 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["packages/*"] [workspace.package] -version = "3.0.1" +version = "3.1.0" edition = "2021" # Minimum supported Rust version (MSRV). CI builds the production binary on # exactly this toolchain. See "Supported Rust versions" in DEVELOPMENT.md