Skip to content

fix: verify-ca requires an explicit ssl_ca file - #48

Merged
aesslinger merged 1 commit into
mainfrom
fix/verify-ca-requires-explicit-ca-file
Aug 19, 2026
Merged

fix: verify-ca requires an explicit ssl_ca file#48
aesslinger merged 1 commit into
mainfrom
fix/verify-ca-requires-explicit-ca-file

Conversation

@aesslinger

Copy link
Copy Markdown
Collaborator

Summary

verify-ca without an explicit ssl_ca file silently fell through to with_platform_verifier() — full OS-trust-store validation — instead of erroring. The builtin driver's build_postgres_tls_connector requires an explicit CA file for this mode (platform roots aren't used, since macOS's strict EKU check rejects them) and errors clearly otherwise.

Fixes #46.

Discovery context

Found while implementing #44's fix, tracing which ssl_mode/ssl_ca combinations reach the with_platform_verifier() fallback branch. Distinct, smaller discrepancy from #44 (which was about require's cert-validation logic) — filed separately and intentionally left out of #47.

Fix

Added the same guard as the builtin, adapted to this plugin's param-name-based error convention (references ssl_ca by name, since these come from JSON params rather than a UI form):

if params.ssl_mode.as_deref() == Some("verify-ca") && user_ca.is_none() {
    return Err(
        "verify-ca mode requires an explicit CA file via ssl_ca. Platform \
         root certificates are not used for this mode. For automatic \
         platform trust, use verify-full instead."
            .to_string(),
    );
}

verify-full without ssl_ca is unaffected — that's the actual distinction between the two modes (verify-full is documented to fall back to platform trust automatically; verify-ca is not).

Testing

Manual live verification against the same self-signed-cert SSL-enabled PostgreSQL instance used for #44/#47:

Scenario Before After
verify-ca, no ssl_ca {"error":{...,"message":"...error performing TLS handshake"}} (confusing) {"error":{...,"message":"verify-ca mode requires an explicit CA file via ssl_ca..."}} ✅ (clear)
verify-full, no ssl_ca fails (self-signed cert not in platform trust — correct) unchanged ✅
require succeeds (per #47) unchanged ✅

Automated: new unit test build_tls_connector_verify_ca_without_ssl_ca_returns_a_clear_error, confirmed failing before the fix (the current code returned Ok) and passing after. Existing verify-ca-with-ssl_ca tests (verify_ca_cert_verifier_*, build_tls_connector_verify_ca_*) all still pass, confirming no regression in the actual chain/hostname validation logic.

Test plan

  • cargo test --lib --bins — 114/114 pass (113 previous + 1 new)
  • Manual live verification against real non-SSL and SSL-enabled PostgreSQL instances (table above)
  • cargo clippy --all-targets -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • cargo build --release — clean
  • npx markdownlint CHANGELOG.md — clean

verify-ca without an explicit ssl_ca silently fell through to
with_platform_verifier() -- full OS-trust-store validation -- instead
of erroring. The builtin driver's build_postgres_tls_connector
requires an explicit CA file for this mode (platform roots aren't
used, since macOS's strict EKU check rejects them) and errors clearly
otherwise ("verify-ca mode requires an explicit CA file...").

Added the same guard, adapted to this plugin's param-name-based error
convention (references ssl_ca by name, since these come from JSON
params rather than a UI form). verify-full without ssl_ca is
unaffected -- that mode is documented to fall back to platform trust
automatically, which is the actual distinction between the two modes.

Proved the fix live against the same self-signed-cert SSL-enabled
PostgreSQL instance used for #44/#47: verify-ca with no ssl_ca
previously failed with a confusing generic "error performing TLS
handshake"; now returns a clear, actionable error. Confirmed
verify-full and require remain unaffected.

Fixes #46.
@github-actions

Copy link
Copy Markdown

Version suggestion

Based on this PR's title (fix) and the prerelease:beta label:

Current 1.0.0-beta.7
Suggested next tag v1.0.0-beta.8

This is informational only — no tag or release is created automatically yet.

@aesslinger
aesslinger merged commit fd68900 into main Aug 19, 2026
13 of 14 checks passed
@aesslinger
aesslinger deleted the fix/verify-ca-requires-explicit-ca-file branch August 19, 2026 15:18
aesslinger added a commit that referenced this pull request Aug 19, 2026
Continuation of the beta line after PRs #45/#47/#48 (ssl_mode=require/
verify-ca/verify-full silently allowing plaintext, ssl_mode=require
validating against the platform trust store instead of skipping
validation, and verify-ca silently falling back to platform trust
instead of requiring an explicit CA file).

Also corrected three README claims that had gone stale across this
session's TLS work: the ssl_mode value list was missing allow/prefer
in two places, ssl_ca's description didn't note it's now required
(not just optional) for verify-ca, and the pool-caching description
still said host:port:database:user, missing startup_script and every
TLS param folded in by #37.

Verified: .tabularium re-validated clean against the live registry
schema; cargo build/test (114/114)/clippy/fmt all pass; markdownlint
clean; manual live-TLS smoke tests against real non-SSL and
self-signed-cert SSL-enabled PostgreSQL instances covering every
ssl_mode value and error path all behave as documented.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prerelease:beta Version suggestion targets a beta prerelease

Projects

None yet

Development

Successfully merging this pull request may close these issues.

verify-ca without an explicit ssl_ca file silently falls back to platform trust (builtin errors instead)

1 participant