v0.2.0 — Security hardening + new tools
A security-hardening and capability release. No live exploit existed in 0.1.x, but the SQL whitelist relied entirely on the read-only connection; this release makes the validator independently sufficient, closes information-leak channels, fixes two correctness crashers, and adds two new tools.
🔒 Security (defense-in-depth)
- Validator no longer depends on the read-only GUC alone — rejects data-modifying CTEs (
WITH x AS (DELETE … RETURNING *) …),SELECT … INTO, andEXPLAIN ANALYZEover write statements. - Blocked dangerous function calls —
pg_read_file,lo_*,dblink,set_config(exfiltration/escape vectors even under read-only). - Sensitive-column redaction (default on) — values of
password/token/api_key/secret-like columns are replaced with<redacted>inquery/sample/analyze. Metadata columns (token_count,password_changed_at,otp_enabled) are not affected. Disable withredact_sensitive = false. - Sanitized connection errors — host/user/dbname no longer leak to the agent; full detail goes to the server log only.
- Resource bounds —
max_profile_rowsgate foranalyze/anomalies, schema/FK/index caps,comparededup + cap (with a visible note), config upper bounds, sessionstatement_timeout+idle_in_transactionbackstops. - Identifier regex uses
\Z(trailing-newline safe);$1is treated as a positional parameter, not a dollar-quote tag.
🐛 Correctness
- Fixed
numeric(20,2)overflow on largeSUM/AVGinanalyze/trend. - Per-column probes run inside savepoints — a failed probe is skipped (reported via
skipped_columns) instead of aborting the whole profile; timeouts still propagate. trendvalidates column types up front (clear errors instead of opaque failures).- Row counts are labeled as planner estimates (
~N rows est.).
✨ New capabilities
describe— single-table schema + indexes (much cheaper thanschemaon large databases).explain— query plan cost/row estimates without executing the query.querygainsoffsetpaging andformat="json".- Cells render
NULL/bytes/JSON safely; display truncation is marked with an ellipsis.
🧰 Robustness / ops
main()validates config eagerly at startup and forces logging to stderr (stdout is the MCP channel).${ VAR }placeholders tolerate inner whitespace.
✅ Tests / CI
- Test suite expanded 89 → 179 (read-only option, redaction, savepoint isolation, timeout budget, identifier-injection boundaries, new tools, full server tool layer).
- CI pins ruff via dev extras and adds a build + wheel-import job.
Tools: 11 → 13 (added describe, explain). Backward-compatible; the one behavior change is redaction defaulting on.
Install: `pip install dbecho`