What's new since v0.20.4
A feature release introducing Tor access control — a deny-by-default egress-control subsystem spanning four enforcement vectors, built out across four phases plus per-command audit attribution — alongside client-side Watchtower policy-resolution wiring. Built from the same commit validated by v0.20.5-rc1.
Features
- Tor access control (deny-by-default) — a new
tor:policy subsystem that controls Tor usage across four vectors: launching Tor client binaries (vectors.processes/client_binaries), connecting to local SOCKS/control ports (vectors.socks_ports/socks_ports/control_ports), reaching known relay IPs (vectors.relay_ips, seeded from the Tor directory authorities plus an optional onionoorelay_feed), and resolving or serving.onionaddresses over DNS and HTTP (vectors.onion). Modes:deny(block) oraudit(observe only) (#424). - Onion gateway (allow-mode) — set
tor.mode: allowwithonion_rulesto permit specific.onionservices and deny the rest. A SOCKS5 front-end terminates the client handshake and filters per-.onionagainst the rules, forwarding allowed targets to the real Tor SOCKS daemon and failing closed on anything unmatched (#428). - Onion-gateway fail-open closed — all configured
socks_portsare force-redirected into the gateway (loopback DNAT inside the session network namespace) and each session gets a fail-closed deny clone, so Tor traffic can no longer bypass the per-.onionfilter by talking straight to a loopback daemon (#429). - Command-aware gateway (SOCKS RESOLVE) — the gateway now filters and forwards SOCKS
RESOLVE(0xF0) through the sameonion_rules, so a permitted client can resolve a name through Tor without a DNS leak;RESOLVE_PTR(0xF1) and other commands are rejected with the correct SOCKScommand not supported(0x07) code (#430). - Per-command attribution on Tor events — the
onion_dns,onion_http, onion-gateway, andrelay_ip/socks_porttor_controlaudit events now carry the originating command's PID instead of0, lining them up with the ptrace-path Tor events for cross-referencing (#431). - Watchtower: decision-context reporting — agentsh now reports
DecisionContextto Watchtower so policy can be resolved server-side (#426). - Watchtower: client-side instance authentication (v1) — per-instance authenticated transport to Watchtower over WTP via a pluggable credential source (#427).
Operator-visible behavior changes
- New top-level
tor:config block, off unlesstor.enabled: true. With it enabled, the defaultmode: denyblocks all four vectors;auditobserves without blocking;allowactivates the onion gateway whenonion_rulesare present. Relevant knobs:vectors.{processes,socks_ports,onion,relay_ips},client_binaries,socks_ports,control_ports,socks_loopback_only,relay_feed.{enabled,sources,sync_interval,cache_dir}, andonion_rules[].{onion,decision}. - In
allowmode, all configuredsocks_portsare force-redirected through the gateway and unmatched/denied onions fail closed — a Tor client that previously reached a loopback SOCKS daemon directly is now subject to the per-.onionfilter. - Tor enforcement surfaces as
tor_controlaudit records (vectors:process,socks_port,relay_ip,onion_dns,onion_http,onion,gateway), which now include the originating command PID. - Operators integrating with Watchtower: agentsh now sends decision context and authenticates per instance over WTP; existing deployments without Watchtower are unaffected.
Validation
Built from the same commit as v0.20.5-rc1 and published through the full release matrix (goreleaser, alpine-build, signed macOS app, Homebrew cask, checksums). One post-publish integration-test leg (docker-test rockylinux10) hit a transient Rocky Linux mirror outage unrelated to the release; the artifacts were unaffected and the leg is hardened for future releases in #432. The rc1 prerelease is retained.
Full changelog: v0.20.4...v0.20.5