Skip to content
Merged
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
85 changes: 85 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,91 @@ jobs:
channel: engineering
webhook_url: ${{ secrets.SLACK_NOTIFICATION_WEBHOOK_URL }}

# Toolchain checks outside the pinned toolchain. Neither needs PostgreSQL,
# credentials, or the test matrix.
#
# MSRV: builds the production binary on `rust-version` from Cargo.toml, so a
# change that raises the compiler requirement fails here.
msrv:
name: Build (Rust MSRV)
runs-on: blacksmith-16vcpu-ubuntu-2204
timeout-minutes: 30

steps:
- uses: actions/checkout@v4

- name: Read MSRV from Cargo.toml
id: msrv
shell: /bin/bash -l {0}
run: |
set -euo pipefail
# Read the root manifest directly: cargo itself would need the
# rust-toolchain.toml toolchain installed first.
msrv=$(sed -n 's/^rust-version = "\(.*\)"$/\1/p' Cargo.toml)
if [[ -z "${msrv}" ]]; then
echo "::error::Cargo.toml [workspace.package] has no rust-version"
exit 1
fi
echo "MSRV: ${msrv}"
echo "version=${msrv}" >> "$GITHUB_OUTPUT"

- name: Install Rust ${{ steps.msrv.outputs.version }}
shell: /bin/bash -l {0}
run: rustup toolchain install "${{ steps.msrv.outputs.version }}" --profile minimal --no-self-update

- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
key: msrv-${{ steps.msrv.outputs.version }}

- name: Build production binary
shell: /bin/bash -l {0}
env:
# Overrides rust-toolchain.toml.
RUSTUP_TOOLCHAIN: ${{ steps.msrv.outputs.version }}
run: |
set -euo pipefail
rustc --version
declared=$(cargo metadata --no-deps --format-version 1 \
| jq -r '.packages[] | select(.name == "cipherstash-proxy") | .rust_version')
if [[ "${declared}" != "${{ steps.msrv.outputs.version }}" ]]; then
echo "::error::cipherstash-proxy rust-version is '${declared}', expected '${{ steps.msrv.outputs.version }}'"
exit 1
fi
cargo build --locked --release --package cipherstash-proxy

# Latest stable: early warning that a new Rust release breaks the build or
# adds Clippy lints, before the pinned toolchain is bumped to it.
stable:
name: Lint (Rust stable)
runs-on: blacksmith-16vcpu-ubuntu-2204
timeout-minutes: 30
env:
# Overrides rust-toolchain.toml.
RUSTUP_TOOLCHAIN: stable

steps:
- uses: actions/checkout@v4

- name: Install latest stable Rust
shell: /bin/bash -l {0}
run: |
rustup toolchain install stable --profile minimal --component clippy,rustfmt --no-self-update
rustc --version

- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
key: stable

- name: Check formatting
shell: /bin/bash -l {0}
run: cargo fmt --all -- --check

- name: Clippy
shell: /bin/bash -l {0}
run: cargo clippy --locked --all --no-deps --all-targets --all-features -- -D warnings

burn-in:
name: Encrypted burn-in (PostgreSQL 17)
runs-on: blacksmith-16vcpu-ubuntu-2204
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### Changed

- **Minimum supported Rust version**: building Proxy from source now requires Rust 1.89.0 or later, declared as `rust-version` in `Cargo.toml` so Cargo reports an older compiler clearly instead of failing deep in a dependency. CI builds the production binary on Rust 1.89.0 to keep that minimum from rising by accident. Development, tests, and release binaries use the Rust version pinned in `rust-toolchain.toml` (currently 1.99.0). See [Supported Rust versions](DEVELOPMENT.md#supported-rust-versions).

- **PostgreSQL execution lifecycle ownership**: Proxy now tracks prepared statements, portals, Describe operations, execution outcomes, and execution metrics as one connection-local protocol lifecycle. Suspended executions retain their original metrics scope until completion, repeated portal executions receive distinct scopes, and terminal errors replace upstream responses atomically while schema outcomes are reported exactly once.

- **Upstream TLS verification for client traffic**: Connections with `with_tls_verification` enabled now use a cached snapshot of the system root certificates, loaded once when Proxy starts. Unlike Proxy's background database connections, pg-proto client-traffic connections do not apply operating-system revocation checks or enterprise verification policy. Restart Proxy after changing the system trust store.
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ members = ["packages/*"]
[workspace.package]
version = "3.0.1"
edition = "2021"
# Minimum supported Rust version (MSRV). CI builds the production binary on
# exactly this toolchain. See "Supported Rust versions" in DEVELOPMENT.md
# before changing it.
rust-version = "1.89.0"

[profile.dev]
incremental = true
Expand Down
37 changes: 37 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,43 @@ Install development and testing dependencies (including `cargo-binstall`):
mise install
```

### Supported Rust versions

CI uses three Rust toolchains:

| Toolchain | Declared in | What CI runs on it |
|---|---|---|
| **Pinned** (currently 1.99.0) | `rust-toolchain.toml` | Formatting, Clippy, unit and integration tests across the full PostgreSQL matrix, burn-in, benchmarks, and release binaries (`mise run build:binary`). |
| **Latest stable** | floating `stable` channel | `Lint (Rust stable)`: formatting and Clippy only. |
| **Minimum supported (MSRV)** (currently 1.89.0) | `rust-version` under `[workspace.package]` in `Cargo.toml` | `Build (Rust MSRV)`: builds the production binary with `cargo build --locked --release --package cipherstash-proxy`. |

The MSRV build and stable lint jobs need no PostgreSQL or credentials. Locally, rustup selects the pinned toolchain automatically from `rust-toolchain.toml`.

Rust 1.88 cannot build Proxy: a transitive dependency (`stack-profile`, via `cipherstash-client`) uses `std::fs::File::lock`, which stabilized in 1.89, without declaring that requirement.

To run those checks locally:

```shell
cargo +stable clippy --all --no-deps --all-targets --all-features -- -D warnings

rustup toolchain install 1.89.0 --profile minimal
cargo +1.89.0 build --locked --release --package cipherstash-proxy
```

#### Bumping the pinned toolchain

When `Lint (Rust stable)` fails after a new Rust release, fix the new warnings and update `channel` in `rust-toolchain.toml` to that release in the same pull request. The full matrix then confirms the new pin.

#### Raising the MSRV

The MSRV only goes up deliberately. If `Build (Rust MSRV)` fails because a change, or a dependency update in `Cargo.lock`, needs a newer compiler, either avoid the newer requirement (for example, keep the older dependency version) or raise the MSRV in the same pull request:

1. Update `rust-version` in the root `Cargo.toml`. CI picks up the new value automatically.
2. Update the current MSRV and the reason for it in this section.
3. Add a `### Changed` entry to the `[Unreleased]` section of `CHANGELOG.md` naming the new minimum and why it changed, because it affects anyone building Proxy from source.

Lowering the MSRV requires confirming that `Build (Rust MSRV)` passes on the lower version first.

### PostgreSQL

> [!IMPORTANT]
Expand Down
1 change: 1 addition & 0 deletions packages/cipherstash-proxy-burn-in/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "cipherstash-proxy-burn-in"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
publish = false

[dependencies]
Expand Down
1 change: 1 addition & 0 deletions packages/cipherstash-proxy-integration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "cipherstash-proxy-integration"
version = "0.1.0"
edition = "2021"
rust-version.workspace = true

[dependencies]
bytes = "1.10.1"
Expand Down
1 change: 1 addition & 0 deletions packages/cipherstash-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "cipherstash-proxy"
version.workspace = true
edition = "2021"
rust-version.workspace = true

[dependencies]
async-trait = "0.1"
Expand Down
1 change: 1 addition & 0 deletions packages/eql-mapper-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name = "eql-mapper-macros"
description = "Macros to reduce boilerplate in the implementation of eql-mapper"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
publish = false

[lib]
Expand Down
1 change: 1 addition & 0 deletions packages/eql-mapper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name = "eql-mapper"
description = "The SQL transformation layer of CipherStash Proxy. Safely transforms SQL to SQL+EQL using a reference schema and type inference approach"
version = "1.0.0"
edition = "2021"
rust-version.workspace = true
authors = [
"James Sadler <james@cipherstash.com>",
"Yuji Yokoo <yuji@cipherstash.com>",
Expand Down
1 change: 1 addition & 0 deletions packages/showcase/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "showcase"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
description = "Healthcare data model demonstrating EQL v3 searchable encryption with realistic encrypted application patterns"

[dependencies]
Expand Down
Loading