Skip to content

fix(duckdb): trust a private CA, pin certificates and tunnel remote Quack connections - #4021

Merged
datlechin merged 2 commits into
mainfrom
fix/duckdb-quack-tls
Nov 3, 2026
Merged

datlechin merged 2 commits into
mainfrom
fix/duckdb-quack-tls

Conversation

@datlechin

@datlechin datlechin commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Remote DuckDB (Quack) gets its own SSL Mode on the General tab: Automatic (Quack's own rule), Disabled, Required (skip verify), Verify Identity with an optional CA file, and Verify Fingerprint. DuckDB never reads the macOS keychain, so a private CA such as mkcert's now works through the CA file, and the certificate quack_serve generates works through its fingerprint. Verify Identity adds the CA to the system bundle, so public HTTPS reads keep working.
  • The Network tab's SSL section no longer shows for DuckDB: nothing there ever reached the driver. Local File mode has no Network tab at all.
  • Remote DuckDB connects through an SSH tunnel, Cloudflare Tunnel, SOCKS proxy or tunnel command. The app forwards a tunnel to the server fields a type declares (curated ServerEndpointFields), and opens a stored tunnel only where the driver dials it. Modes that check the host name are refused through a tunnel before dialing.
  • The Remote session opens with DuckDB's persistent secrets off, the Token is required, and the token lives in a temporary secret dropped right after ATTACH. A secret in ~/.duckdb can no longer replace the token or the trust the form chose, and a later ATTACH to another host cannot pick the token up.
  • A row whose SSL Mode the installed DuckDB driver predates is refused with a pointer to the update, instead of connecting unchecked.
  • quack:// URLs carry sslmode and ssl_fingerprint, and ssl=true means Verify Identity. Every +ssh URL now encodes its database path, and IPv6 hosts are bracketed on copy and unbracketed on import.
  • A failed Quack download reports its cause, and certificate errors name the field to change.
  • The Drop prompt no longer offers "Ignore foreign key checks" for DuckDB, ClickHouse, SQL Server, SurrealDB, Teradata and Beancount, which have no such switch. Beancount and Memcached keep their Ledger and Server labels after the plugin loads. apple/scripts/ci/check-capability-parity.py keeps those flags in step between the curated table and each plugin; it replaces HealthMonitorOptOutParityTests, a test that read source.

Test plan

  • TableProDuckDBCoreTests (new, 48): every SSL Mode direct and through a tunnel, refusals, the secret's lifetime, the combined CA bundle, error mapping, extension loading.
  • TableProTests: the tunnel, transport, URL, field trust, form and refusal suites (507 and 367 cases), including new DriverSettingNotSupportedErrorTests. The deleted HealthMonitorOptOutParityTests is covered by the parity check and its fixtures (test_check_capability_parity.py).
  • apple/scripts/probes/check-quack-tls.sh against DuckDB v2.0.0 (quack f96420ed, httpfs 77392a7): every case passes, direct and through a loopback forward, with stored secrets and a control.
  • AllPlugins builds, all 48 plugins load, R1 and R2 are clean.
Before After
Before, Network tab After, General tab
Before, dark After, General tab, dark

After, Connect via in Remote mode
After, Connect via, dark
After, Local File has no Network tab
After, Local File, dark

Docs: TableProApp/docs#174, merges after this one.

Reported by email; no issue.

…uack connections

Remote DuckDB never used the SSL settings the Network tab showed, and DuckDB
checks certificates against /etc/ssl/cert.pem, not the macOS keychain, so a
server with a private or self-signed certificate could not be reached.

- Remote mode has its own SSL Mode: Automatic, Disabled, Required, Verify
  Identity with an optional CA file, and Verify Fingerprint.
- Tunnels forward to the server fields a type declares, and a stored tunnel
  opens only where the driver dials it.
- The Remote session ignores persistent DuckDB secrets, requires the Token,
  and drops its token secret right after ATTACH.
- An older driver is refused a setting or a tunnel it cannot secure.
- quack:// URLs carry sslmode and ssl_fingerprint; +ssh paths are encoded and
  IPv6 hosts bracketed.
- Curated and plugin capabilities are checked for parity in Repo Hygiene,
  fixing the foreign key checkbox and container names it found.
@datlechin datlechin added backport release/0.84 Merged into main; pick onto release/0.84 backport release/0.85 Merged into main; pick onto release/0.85 labels Nov 3, 2026
@datlechin
datlechin merged commit 113347a into main Nov 3, 2026
10 of 11 checks passed
@datlechin
datlechin deleted the fix/duckdb-quack-tls branch November 3, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport release/0.84 Merged into main; pick onto release/0.84 backport release/0.85 Merged into main; pick onto release/0.85

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant