Repository navigation
test(storage): replay the capture over TLS in the parity oracle - #915
Merged
Merged
Conversation
The oracle started Postgres without TLS, so nothing exercised a server that insists on it. It now starts a second server with ssl=on and a per-run self-signed pair, and the same replay runs over sslmode=require, compared op by op against the TypeScript capture and against the plaintext run; pg_stat_ssl confirms the session the server sees. The postgres image runs as uid 70 and PostgreSQL refuses a 0600 key it cannot read, so that server runs as the invoking uid with its own PGDATA on a bind, keeping the key 0600. With tls-none restored the leg fails to connect instead of falling back. Fixes #911.
🦋 Changeset detectedLatest commit: 0ad608e The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
[Low impact] The PR appears safe to merge; both previous findings are addressed.
|
Two runs of the oracle shared .test-reports/parity-tls, so a second run deleted the first one's live PGDATA. The directory now carries the pid and a random token and the exit trap removes it, so concurrent runs (on different ports) cannot touch each other. The TLS test returned early without a TLS URL, which also printed '1 passed', so the script's pass-count check could not tell a skip from a run. PARITY_TLS_REQUIRED makes the test panic instead of skipping, and a completion marker printed after the assertions is what the script checks.
chappie-daemon
force-pushed
the
factory/911-tls-parity
branch
from
October 20, 2026 02:49
07090bc to
0ad608e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
scripts/storage-parity.shnow starts a second Postgres that requires TLS and replays the same capture over it. Fixes #911.What the leg does
A second
postgres:16-alpinestarts withssl=onand a self-signed pair generated per run, publishing onPARITY_PG_TLS_PORT(default 18778). Ports, the per-run password, theorg.testcontainers=truelabel, the single-address bind and the exit trap are unchanged; the only new bind sources are the certificate pair and that server's PGDATA, both inside the worktree under.test-reports/parity-tls-<pid>-<random>/, translated to the daemon's view the wayscripts/rust.shtranslatesthe source tree (
NOSTREAM_HOST_DIRoverrides). The directory is per invocation and removed by the exit trap, sotwo oracle runs cannot delete each other's live PGDATA.
The test is
the_same_replay_over_tls_matches_the_capture_and_the_plaintext_run, and it asserts three things:sslmode=requireconnection works at all;SELECT ssl FROM pg_stat_ssl WHERE pid = pg_backend_pid()is true — the server reports the session encrypted, so a connection string alone cannot pass the leg.with_databasekeeps the query string, sosslmode=requiresurvives into the replay connection the assertion is made over;The step fails if the test does not run, and not merely by counting passes: the script sets
PARITY_TLS_REQUIRED,under which the test panics instead of skipping when it has no TLS URL, and it greps for a
TLS_PARITY_COMPLETEline that the test prints only after its assertions. A skip, a rename and an early returnall fail the run — measured: with
PARITY_TLS_REQUIRED=1and no URL the test fails withPARITY_TLS_REQUIRED is set but PARITY_TLS_ADMIN_URL is not. In CI's existingStorage paritystep neithervariable is set, so the test prints that it is skipping and returns; the oracle is where the leg runs.
The uid-70 trap, and how it is handled
The official image's
postgresuser is uid 70, and PostgreSQL refuses a key with group or world access (private key file ... has permissions ... u=rw (0600) or less), so a host-generated0600key is unreadable to it andchmod 644is not accepted either. The server therefore runs as the invoking uid (--user "$(id -u):$(id -g)") with its ownPGDATAon a bind: the key stays0600, owned by the user the server runs as, and the image is unmodified. No host step is needed; the script does it.Oracle output
PARITY_BIND=100.106.134.5 PARITY_HOST=100.106.134.5 RUST_CACHE_VISIBLE=/workspace/containers/rust-builder/cache NODE_PATH=/workspace/projects/nostream/node_modules ./scripts/storage-parity.shon this head, exit 0:Baseline for comparison: the same command on
6ef609apasses the three original steps with 118 scenarios; this run keeps every one of them and adds the fourth.Controls, at two layers
The build,
tls-none. A scratch copy withCargo.tomlback totls-nonefails — but earlier than the TLS leg, in the behavioural step, at the guard #913 merged:So the two tests cover different layers rather than repeating each other: the guard pins the build, the leg pins the server handshake and the replay equality. Because the run aborts at the guard, the leg's own control is a server-side change, not the feature flag.
The server,
ssl=off. The same TLS leg pointed at a Postgres with TLS off, atsslmode=require:That is the leg's own negative control: no fallback to plaintext, and the failure names the server rather than the build.
Local checks
cargo fmt --all --checkclean;cargo clippy --workspace --all-targets --all-features -- -D warningsclean;cargo test --workspace --all-features594 passed, 0 failed.