Skip to content

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 20 May 16:01
· 59 commits to main since this release
f5833e1

What's new since v0.19.3

This is a feature + hardening release. The headline change is a full PostgreSQL access proxy for agentsh, landed in eleven planned steps (Plan 01–Plan 12); together they add wire-level Postgres interception, classification, policy evaluation, redirect runtime, and a real-Postgres integration suite. Alongside it, a wave of sandboxing and wrap fixes — including the late v0.20.0-rc1 regression #361 — make the wrapper path more robust on hosted runtimes (Vercel/Daytona/Firecracker), and the file-monitor / FUSE / eBPF layers each pick up multiple correctness fixes.

Database access (PostgreSQL)

  • Taxonomy and effects type backbone (#294) — DB Plan 01. Introduces the database access type system: operation taxonomy, effect modeling, and the core types every later plan plugs into.

  • Policy evaluator (#295) — DB Plan 02. The DB policy evaluator that maps taxonomy + effects to allow / deny / approve / redirect decisions.

  • PostgreSQL classifier (#297) — DB Plan 03. SQL → taxonomy classifier covering reads, writes, DDL, DCL, transaction control, and Postgres-specific constructs.

  • PostgreSQL proxy listener skeleton (#298) — DB Plan 04a. Listener, connection acceptance, and the Postgres wire-protocol skeleton.

  • Inbound PostgreSQL handshake + TLS termination (#299) — DB Plan 04b. Startup, AuthenticationOk, parameter negotiation, optional TLS termination of the inbound leg.

  • PostgreSQL upstream wiring + passthrough modes (#300) — DB Plan 04b₂. Dials the configured upstream, supports passthrough and inspect modes for the connection lifecycle.

  • Simple Query path + DBEvent emission (3da3c49d) — DB Plan 04c. Inspects Simple Query (Q) statements, emits classified DBEvents through the same event broker used by exec/audit.

  • Extended Query + transaction state machine (#307) — DB Plan 05a. Parse / Bind / Describe / Execute / Sync flow with explicit transaction state tracking.

  • SQL prepared cache + FunctionCall opt-in + classifier escalation wiring (#319) — DB Plan 05b. Prepared-statement cache, opt-in FunctionCall (F) handling, and classifier escalation hooks for ambiguous statements.

  • COPY approval runtime (3c03e063) — DB Plan 05c. Routes COPY operations through the approval/redirect runtime so bulk loads can be gated like any other DB effect.

  • Postgres cancel-request mapping (#321) — Maps inbound CancelRequest packets to the right upstream backend so query cancellation works through the proxy.

  • Runtime auth events (#324) — DB Plan 07b. Emits structured auth events (success/failure, identity) for the DB proxy alongside normal request events.

  • Real Postgres integration suite (#325) — DB Plan 07c. Adds an integration test suite that exercises the proxy against a real PostgreSQL instance covering the protocol paths landed in 04/05.

  • DB Phase 2 roadmap + catalog resolver foundation (#326) — Roadmap doc and the catalog resolver primitive that later plans build on.

  • Runtime resolution integration (#327) — DB Plan 09. Threads catalog resolution through the runtime so policy decisions reference real schema objects.

  • Policy ergonomics (#329) — DB Plan 10. Higher-level policy shorthands for common DB rules.

  • Redirect planner (#335) — DB Plan 11. Plans rewrites/redirects for matching statements.

  • Redirect runtime integration (1fda06c1) — DB Plan 12. Wires the planner output into the live proxy so redirects are applied end-to-end.

  • Database access unavoidability bundle (54efd688) — Documents and exercises the security argument that DB policy is unavoidable for proxied connections.

Sandboxing & security — wrap, seccomp, eBPF, ptrace

  • wrap-init refuses when sandbox.unix_sockets.enabled=false (#362, #363, #364, refs #361) — v0.20.0-rc1 regressed every secure-sandbox deployment that disables seccomp at the server level (Vercel Firecracker, Daytona, E2B custom images): the shim engaged agentsh-unixwrap despite unix_sockets.enabled: false, loaded a seccomp filter, and the notify-fd handshake failed because the server had no handler — every exec involving env-var expansion or network calls silently exited with empty stdout and exit 1. Fixed in three PRs: the server-side gate (#362), an integration regression guard (#363), and the policy-limits bypass close-out (#364) where secure-sandbox's default resource_limits had been keeping the wrapper engaged through wrapNeedsCgroupBeforeAck even when no enforcement infrastructure was configured. New unit + integration tests pin all three contracts against the exact config secure-sandbox emits.

  • Harden eBPF coverage in wrap (#344) — Tightens how the wrapper attaches eBPF for sessions so coverage holds across the same edge cases that previously slipped through.

  • eBPF attach-only cgroup mode (#347, #348) — New mode where agentsh creates the cgroup and attaches BPF, but does not try to enable controllers in subtree_control. This is the right behavior on hosts that allow cgroup mkdir+attach but not controller-enable (common on Firecracker / Daytona kernels).

  • Warn when eBPF is enabled but cgroups is not (#346) — Surfaces the misconfiguration explicitly instead of silently degrading, and documents the docker prereqs.

  • Pad eBPF AllowKey to 32 bytes to match BPF map key_size (#350) — Fixes a layout mismatch between userspace key construction and the BPF map definition.

  • Pin OS thread before raw seccomp(2) syscall (#318) — Prevents Go's M-to-P thread movement from delivering the seccomp(2) syscall to a different OS thread than the one carrying the no-new-privs / filter-attach state.

  • Link against system libseccomp 2.5 (#316, closes #296) — Uses the system libseccomp at the 2.5 ABI rather than carrying our own.

  • ptrace sessionless pid-attach + reviewed seed helper (#292) — Lets the ptrace tracer attach to a PID without a pre-existing agentsh session, and reworks the seed helper after the security review.

  • Include agentsh-unixwrap in the default make target (#308) — The wrapper binary is now built by the default packaging target.

  • Skip file_monitor auto-enable when socket_rules are set (#358, closes #304) — Auto-enabling file monitoring alongside socket rules deadlocked the unixwrap during seccomp setup (file syscalls on the setup path block on a notifFD that hasn't been forwarded yet). Auto-enable now respects the operator's explicit socket-rule intent; users who want both can still opt in with file_monitor.enabled: true.

  • shellparse admits safe shell-mode flags alongside -c (#330, #331) — Recognizes additional safe shell-mode flags when parsing wrapped shell invocations, so policy sees the right inner command.

File monitor / FUSE

  • Use the backing-path policy in FUSE extra-ops + cross-mount tests (#328) — checkWithExist resolves to the real backing tempdir before calling CheckFile, so TestFUSE_InterceptsExtraOps and TestFUSE_CrossMountIntoWorkspaceEmitsCreate now allow the resolved backing path rather than virtual /workspace/** — keeping the intercepted code paths exercised on hosts where the FUSE mount actually runs.

  • Pass through Fsync / Flush / Lseek on the FUSE fileHandle (#309) — Adds the missing pass-through ops on the FUSE file handle so workloads that rely on them keep working under the monitor.

  • Close eventChan on fs.Mount() error path (#351) — mountFUSEForSession now closes the event channel on the mount error path; previously a half-initialized session could leak the channel.

  • Make FUSE MaxBackground tunable (#314) — sandbox.fuse.max_background controls the kernel-side per-mount FUSE async request queue depth (the FUSE_INIT max_background value go-fuse passes). 0 = leave go-fuse's default (12) in place; common tuned values are 32–128 for multi-mount daemons under heavy ptrace+seccomp traffic.

  • Don't treat truncate as destructive under soft_delete (#310) — truncate is no longer routed through soft-delete, which had incorrectly intercepted it as a destructive operation.

  • Filter read-only openat file-monitor events (e1438cfd) — Read-only openats no longer produce file-monitor events when they don't change anything actionable.

  • Fix FUSE event-channel panic (ad8d3b64) — Resolves a panic in the FUSE event channel.

DB & event-stream reliability

  • Drain watchtower live reader on entry (55e926c7) — Drains any buffered events from the watchtower live reader when it starts so downstream consumers don't race on stale entries.

Docker test reliability

  • Probe wait_killable via unixwrap stderr, not server.log (#332) — Probing the wrong stream made the docker-test check brittle.

  • Drop misplaced wait_killable check (#334) — Follow-up cleanup to the probe path.

  • Rocky image path + ubuntu slog stderr leak (#337) — Fixes the rockylinux image reference and stops slog from leaking onto ubuntu's stderr during shim tests.

  • Filter slog from all shim-test captures (ubuntu) (#340) — Generalizes the slog-stderr filter so every shim-test capture is clean.

Demos & CVE write-ups

  • CVE-2026-43284 (Dirty Frag) — socket_rules attack surface demo (702c7533) — Before/after demo showing how the v0.19.3 dirtyfrag-conservative mitigation closes the attack surface; includes a #304 workaround during recording.

  • CVE-2026-31431 (Copy Fail) — page-cache LPE before/after agentsh (#306, 2e538f6f, ad45d0cb) — Recordings, demo.html, and narrative updates. The final narrative makes clear that AF_ALG is blocked by default, and the demo also shows the explicit socket_rule form for operators who want to make it visible.

  • CVE-2025-32463 (sudo chroot NSS LPE) Docker demo (30aefc36, a4041fdd, 54b92f6d) — Reproducer Docker image with the asciinema cast (and animated GIF), plus the demo.html playback page.

Documentation

  • DB access spec v0.8 + pressure-test redline (ff5b0128, 92d3f27b, 6c814d76) — Pressure-tested the v0.7 db-access-spec, applied the redline as v0.8, and replaced v0.7 in the canonical docs path.

  • DB-access Phase 1 implementation roadmap (137897b3) — The roadmap document that drives Plans 01–12.

  • Per-plan design + implementation plans (b53813c3, b245bb81, 66d3d17a, 7d37aebe, 62cbdf9e) — Implementation plans / designs for DB Plan 01, 11, and 12.

  • Plan 05b reconcile with post-05a code state (38b6a220) — Doc-only follow-up reconciling Plan 05b with what actually landed in 05a.

Validation

The final v0.20.0 Release workflow ran the full matrix and all jobs passed:

  • goreleaser (binaries, archives, GitHub release)
  • alpine-build (amd64 + arm64)
  • docker-test × 8: alpine, archlinux, debian, debian-trixie, fedora, rockylinux10, ubuntu, ubuntu2204
  • build-macos-app (signed + notarized)
  • publish-homebrew-cask
  • update-checksums (non-rc DMG SHA256)

v0.20.0-rc1 was recut three times during the cycle to fold in #362 / #363 / #364; v0.20.0 is tagged on the same commit as the final rc1 (f5833e14).

Full changelog: v0.19.3...v0.20.0