You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
test(storage): prove the Postgres backend connects over TLS #911
The Postgres backend built in #910 selects sqlx's tls-none feature, so a server that requires TLS (sslmode=require, sslmode=verify-full) cannot be reached. #910 switches the feature to tls-rustls-ring-webpki, which makes TLS possible; nothing in CI proves it works.
The parity script brings Postgres up without TLS, so every run to date exercises the plaintext path only.
What this needs
A parity leg against a TLS-enabled Postgres: the official image with ssl=on and a generated self-signed pair mounted in, and the connection URL carrying at least sslmode=require.
One assertion that the same op yields the same result over TLS as over plaintext. sslmode=verify-full needs the CA path threaded through the script; require alone is enough to prove the provider is compiled in and negotiated.
A recorded negative control: with tls-none restored, the TLS leg must fail rather than fall back.
Why it is worth an issue rather than a comment
A managed Postgres (the likely deployment) rejects plaintext connections. The failure mode without this is a backend that builds, passes every test, and cannot connect to the database it was written for.
State after #913, measured, so this does not have to be re-derived.
Done there:sqlx now enables tls-rustls-ring-webpki, and a committed guard exists in the parity target — a_tls_connection_is_attempted_rather_than_refused_by_this_build. It opens sslmode=require; if the server offers TLS it runs SELECT 1, and if it does not it requires the server to refuse, never this build. With tls-none restored the test fails with TLS upgrade required by connect options but SQLx was built without TLS support enabled, so the assertion bites.
Measured at runtime, not committed: against postgres:16-alpine with ssl=on and a self-signed pair, the merged build completed the handshake at sslmode=require and SELECT 1 returned 1; the same build against a plaintext server took the refusal branch.
What is left, and why it is not a five-line change: a parity leg in scripts/storage-parity.sh needs the TLS-enabled Postgres inside the script's own lifecycle. That container runs as uid 70, so a host-generated 600 key is unreadable to it — the leg needs the key generated into a path the postgres user owns, or --user/PGDATA rearranged, and that differs per host. It has to be run end to end on the host that will use it, not added blind.
The leg connects with sslmode=require, confirms encryption server-side rather than from the connection string (SELECT ssl FROM pg_stat_ssl WHERE pid = pg_backend_pid()), and replays the full 118-op capture over TLS, matching both the capture and the plaintext run. The negative control pins the layer: with tls-none restored, the run dies at the guard with "TLS upgrade required by connect options but SQLx was built without TLS support enabled", before the leg is reached.
The uid-70 blocker recorded when this issue was filed is gone without a host step: the Postgres container runs as the invoking uid with its own PGDATA on a bind, so the 0600 key is owned by the user the server runs under. chmod 644 was rejected on purpose — PostgreSQL refuses a group-readable key and exits.
Verified end to end on the merged head, not only on the PR: storage-parity exit 0, all four steps, 118 scenarios.
Activity
chappie-daemon commentedon Oct 20, 2026
State after #913, measured, so this does not have to be re-derived.
Done there:
sqlxnow enablestls-rustls-ring-webpki, and a committed guard exists in the parity target —a_tls_connection_is_attempted_rather_than_refused_by_this_build. It openssslmode=require; if the server offers TLS it runsSELECT 1, and if it does not it requires the server to refuse, never this build. Withtls-nonerestored the test fails withTLS upgrade required by connect options but SQLx was built without TLS support enabled, so the assertion bites.Measured at runtime, not committed: against
postgres:16-alpinewithssl=onand a self-signed pair, the merged build completed the handshake atsslmode=requireandSELECT 1returned 1; the same build against a plaintext server took the refusal branch.What is left, and why it is not a five-line change: a parity leg in
scripts/storage-parity.shneeds the TLS-enabled Postgres inside the script's own lifecycle. That container runs as uid 70, so a host-generated600key is unreadable to it — the leg needs the key generated into a path the postgres user owns, or--user/PGDATArearranged, and that differs per host. It has to be run end to end on the host that will use it, not added blind.chappie-daemon commentedon Oct 20, 2026
Closed by #915, merged as
471d439.The leg connects with
sslmode=require, confirms encryption server-side rather than from the connection string (SELECT ssl FROM pg_stat_ssl WHERE pid = pg_backend_pid()), and replays the full 118-op capture over TLS, matching both the capture and the plaintext run. The negative control pins the layer: withtls-nonerestored, the run dies at the guard with "TLS upgrade required by connect options but SQLx was built without TLS support enabled", before the leg is reached.The uid-70 blocker recorded when this issue was filed is gone without a host step: the Postgres container runs as the invoking uid with its own
PGDATAon a bind, so the0600key is owned by the user the server runs under.chmod 644was rejected on purpose — PostgreSQL refuses a group-readable key and exits.Verified end to end on the merged head, not only on the PR:
storage-parityexit 0, all four steps, 118 scenarios.