Skip to content

Releases: Pyronewbic/Sluice

sluice v0.10.0

Choose a tag to compare

@github-actions github-actions released this 17 Jul 12:20
bbb6567

Hardening, supply-chain, and fleet-operations release: fleet-wide egress auditing, a preventive
egress byte cap, pinned/verified replay, and a broad sweep of fail-closed and portability fixes.
All local, self-hosted, no telemetry.

Added

  • Fleet-wide egress auditsluice egress --verify --all / --export --all walk every box's append-only audit log and hash chain with the engine down (no daemon needed). (#67)
  • SLUICE_EGRESS_HARD_CAP_BYTES=N — a preventive in-box egress cap (via xt_quota) that kills an over-cap transfer mid-flight; fails closed when the kernel module is absent. (#67)
  • Per-host egress budget (SLUICE_EGRESS_MAX_BYTES) metered on what left the box; the direct-IP SLUICE_ALLOW_IPS lane is now metered before the ESTABLISHED accept. (#67)
  • sluice lock --pin writes a committable sluice.pin replay manifest (base pinned by digest + exact versions); SLUICE_PIN=1 performs a verified pinned replay build. (#67)
  • Versioned JSON contracts (sluice.version / doctor / box v1); ls --json embeds last_receipt; in-box DNS-tunnel audit and bump upload controls. (#67)
  • sluice egress gains a summary header ("N reached, N blocked, <bytes>"), an audit-log footer nudging --export/--verify, and egress --verify --json for CI integrity gating; egress --json gains "window":"boot". (#43)
  • Denied raw-IP (direct CONNECT/URL) requests are now ledgered in the receipt and egress --json, alongside an always-on fw_dropped total. (#72)
  • New managed-policy directives: max-allow-ips-bytes, max-hard-cap-bytes, strict-unknown, require-signed-base. (#76, #81)
  • sluice doctor readout: trailing verdict line, always-on hardening row, git-tracked-mask warning, report-only managed-policy preflight (doctor --json adds policy.effective_allowlist + policy.refusals), SLUICE_MOUNTS validation, and rootless-podman host-limit checks. (#48, #46, #45, #72, #71)
  • NOTICE file + README Acknowledgments crediting the upstream base image, its packages, and the test framework. (#72)
  • Four capability demo GIFs across the README and docs: a malicious npm dependency contained at import, an exfil killed mid-flight by the hard cap, a fleet audit with the daemon down, and an org policy refusing a metadata-SSRF config.

Changed

  • The credential prelaunch hook now runs before every session (run / shell / rebuild, warm boxes included) so short-lived tokens re-mint each run instead of expiring with the container. (#72)
  • sluice ls ALLOW count reads the live allowlist instead of the stale build-time label. (#72)
  • A config-less first run now stops after scaffolding instead of building + running the detected command under SLUICE_YES=1. (#72)
  • sluice diff is now gated by the managed policy and config validators like every other box bring-up path. (#76)
  • sluice learn drops a laundering host under forbid-laundering / SLUICE_STRICT_LAUNDERING instead of warn-and-keeping it onto the hot-reloaded allowlist. (#76)
  • SLUICE_ALLOW_IPS rejects a hostname entry with a clear message (hostnames belong in SLUICE_ALLOW_DOMAINS) instead of silently sinking it to the DNS dead-end. (#79)
  • sluice lock --scan exit code is a documented contract (0 clean / 3 gate-tripped / 4 scanner-failed), normalized across grype and trivy; --check/--diff/--enforce reject unknown flags. (#44)
  • The SBOM (lock --sbom / --pin) enumerates the full global-npm dependency closure (was top-level only), so a CVE in a transitive npm dep now reaches --scan. (#77)
  • A signed base image is resolved to a content digest once; cosign verify and the Dockerfile FROM pin the same digest (closes a same-tag-republish gap on the :latest signed-base path). (#77)
  • -b <box> doctor resolves the engine leniently, reporting instead of dying on a bad SLUICE_RUNTIME. (#55)
  • Agent presets: gemini drops the inert GOOGLE_API_KEY, qwen forwards DASHSCOPE_API_KEY, and stale/dead allowlist hosts were pruned from claude/amp. (#55, #65, #49)

Fixed

  • Portability (build-breaking): hashing routes through _sha256 (prefers sha256sum, falls back to shasum -a 256), unbricking every build/run on Alpine, *-slim, and most CI images where shasum is absent. (#78)
  • Data-loss: sluice apply/diff exclude masked paths from the overlay write-back, so a masked .env no longer truncates the real host secret to 0 bytes. (#75)
  • Denied raw-IP requests are matched with an interval-free regex, fixing silent under-reporting on mawk builds without --re-interval (e.g. Debian). (#73)
  • Rootless podman keeps host repo ownership via --userns=keep-id; podman's localhost/ image-name prefix is stripped so ls/ps/prune/receipt slugs resolve. (#69, #71)
  • Fail-closed audit reads: ls --egress, learn, and doctor report unknown (? / null) instead of a false all-clear when the in-box audit log can't be read. (#61, #59)
  • set -f around unquoted config word-splits in the launcher and the in-container entrypoint, so a glob char in a SLUICE_* value can't pathname-expand; wildcard allowlist entries stay literal during policy evaluation. (#54, #52, #45)
  • sluice learn no longer aborts when the run-offset file is missing — it falls back to the full log. (#53)
  • SLUICE_SECCOMP=audit writes its generated profile to the stable per-box state dir instead of leaking one /tmp file per run. (#54)
  • The overlay-workspace seed writes its apply-safety manifest only on a fully successful copy, so a partial seed can't delete untouched host files on apply. (#54)
  • egress --verify handles an unterminated final record and skips blank lines (full hash-chain coverage) and rejects typo'd flags. (#42, #55)
  • install.sh re-points origin to SLUICE_REPO on a re-run and quotes a spaced $HOME fpath dir. (#55)
  • lock: LC_ALL=C sorts kill phantom cross-locale drift; same-version rebuilds and multi-version packages classify correctly; --sbom/--json stdout is byte-clean on a cold build. (#44, #42)

Security

  • Closed egress allowlist fail-opens: the leading-dot wildcard form (.storage.googleapis.com) that sluice learn writes now matches forbid-laundering / strict-laundering, and SLUICE_ALLOW_IPS refuses masks broader than /8 (was only /0). (#51)
  • sluice init single-quotes every repo-derived value written into the generated config, closing an RCE via a hostile Procfile / make-target / package.json script. (#50)
  • Closed five managed-policy trust-boundary bypasses: deny-ip refuses an SLUICE_ALLOW_IPS entry that overlaps the denied CIDR in either direction (supernet included, e.g. a /24 over a /32 metadata deny); a malformed ceiling arg is a hard refusal, not a fail-open no-op. (#76)
  • sluice learn fails closed on an unreachable managed policy, aligning it with the run path.

Internal

CI / supply-chain hardening (advisory actionlint / zizmor / gitleaks lanes, checksum-pinned grype + container-structure-test installs, SHA-pinned action bumps), a lane-membership drop-guard and a preflight ship-readiness workflow, added regression coverage, docs-drift fixes, and a consolidated Terraform Linux test-runner VM (sluice-vm.sh, Kata opt-in). (#57, #60, #62, #63, #64, #65, #66, #68, #70, #74, #80, #81)


Install

brew install Pyronewbic/tap/sluice        # or: brew upgrade sluice
# or:  curl -fsSL https://raw.githubusercontent.com/Pyronewbic/Sluice/main/install.sh | sh

Full changelog: v0.9.0...v0.10.0

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 13 Jun 09:38
61cd82d

sluice v0.9.0

A security and auditability release. Egress is now evidence-grade - every run leaves a tamper-evident, hash-chained receipt you can export and verify - on top of a deny-capable central policy and ten adversarially-verified hardening fixes. Plus in-repo secret masking, five more detected stacks, and a rebuilt doc + demo set. Same default-deny egress firewall, non-root box, and project-dir-only mount as before.

Added

  • Evidence-grade egress receipts - every run appends to a host-side, append-only, hash-chained log; sluice egress --verify walks the chain (red on any edit, reorder, or drop) and --export ships it to a SIEM. See docs/operations.md.
  • Central egress policy - a deny-capable, ceiling-setting org policy (/etc/sluice/policy.conf): a deny is final and local config cannot loosen it. A URL-fetched policy is signature-authenticated. See docs/policy.md.
  • SLUICE_MASK - shadow in-repo secrets (.env*, keys) from the box: the path still exists, the contents read empty. sluice doctor flags secret-looking files no pattern covers.
  • SLUICE_OVERLAY_DIRS - give platform-specific dirs (e.g. node_modules) a box-local volume instead of leaking host artifacts into the box.
  • Five more stacks - sluice init now detects Java, PHP, .NET, Elixir, and Dart (11 total), with build-time dependency prefetch (Go/Rust/Ruby/Python) for tighter runtime egress and init --update to refresh detection without clobbering your edits.

Changed

  • Hardened against 10 adversarially-verified findings - a forged-Host plaintext-HTTP exfil path, a uid-1000-writable PATH privilege escalation, a box-rewritten .git cross-repo mount, a mixed-case DoH tunnel, and six more are closed; the egress byte-gate and in-box audit now fail closed. See THREAT_MODEL.md.
  • sluice runs quieter - the build transcript goes to a per-box log (tail replayed on failure), a multi-line run command is summarized on the plan line, and masked paths are counted rather than listed.
  • Supply chain - cosign verification is anchored to the signing-workflow identity, and install.sh pins to an exact commit and reports its sha.
  • Docs + demos rebuilt - a lean README front door plus topic guides (hardening, supply-chain, agents, configuration, operations), and a demo gallery regrouped around real user journeys.

Fixed

  • The boot self-test always runs and proves every default-DROP rule (including the IPv6 stack) before the workload starts.
  • sluice apply no longer deletes host files created mid-session; learn applies the DoH/laundering filter on the live-reload path; lock inventories pip --user/pipx sites, not just system pip.

Verify

Every release ships a deterministic source tarball, SHA256SUMS, and a cosign keyless signature bundle; the multi-arch base image is cosign-signed in GHCR. Verification steps are in SECURITY.md.

Full changelog: v0.8.0...v0.9.0

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 03 Jun 12:53
f34459f

sluice v0.8.0

A security-hardening release. Opt-in sandbox lockdown, a copy-on-write workspace mode, and tighter egress that closes DNS-based exfil tunnels - all on top of the same default-deny egress firewall, non-root box, and project-dir-only mount.

Added

  • Hardened seccomp profile (opt-in) - SLUICE_SECCOMP=hardened runs the box under a tightened syscall filter.
  • Read-only rootfs (opt-in) - SLUICE_READONLY_ROOT=1 makes the container filesystem immutable.
  • Workspace overlay (opt-in) - SLUICE_WORKSPACE=overlay runs against a throwaway copy of the repo; the agent's edits land in a scratch layer you review and apply.
  • Tighter default privileges - drop ALL Linux capabilities and add back only the boot-needed set, plus no-new-privileges, resource bounds, and removal of in-box sudo.
  • DoH/DoT exfil block - DNS-over-HTTPS and DNS-over-TLS resolvers are refused even when their host is allowlisted, closing a covert egress tunnel.
  • No-op run hint - sluice run warns when SLUICE_RUN_CMD is a no-op so a silent success isn't mistaken for a hang.

Changed

  • Test suite migrated to bats-core with a container-structure-test gate (asserts base-image invariants: no sudo, uid 1000, firewall packages). CI runs the gate on Docker and rootless Podman.

Verify

Every release ships a deterministic source tarball, SHA256SUMS, and a cosign keyless signature bundle. Verification steps are in SECURITY.md.

Full changelog: v0.7.0...v0.8.0

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 02 Jun 18:41
6150127

Coding agents, supply-chain verification, and stronger isolation. Run coding agents one-shot inside the sandbox, gate dependencies with vuln scans and a strict lockfile, and optionally give each box its own kernel.

Added

Coding agents

  • sluice agent <name> [args] runs an agent in the sandbox; trailing args run it one-shot (e.g. sluice agent claude -p "fix the failing test"). No name lists every preset with its auth variable and whether that variable is set on your host.
  • Two new presets, qwen and crush, bringing the set to nine (claude, codex, gemini, aider, cursor, opencode, amp, qwen, crush).
  • Pre-run auth check warns when a preset's API-key variable is unset, and a multi-agent guard points you to git worktree when a directory is already wired to a different agent.

Supply chain

  • sluice lock --scan runs a host-side Grype or Trivy vulnerability scan of the box, with --fail-on <severity> to gate the build.
  • sluice lock --enforce makes the lockfile a strict gate (build fails on package drift). Inventory now covers cargo alongside apk/npm/pip/gem/go, and lockfiles export as CycloneDX or SPDX via --format.
  • Base-image SBOM attestation: the published GHCR base image ships a CycloneDX SBOM, cosign-signed keyless.

Isolation

  • SLUICE_RUNTIME=kata runs a box as an own-kernel micro-VM instead of a shared-kernel container, where available.

Control plane

  • sluice -b/--box <name> targets any box from outside its directory; sluice ls gained a posture/orphan dashboard; sluice rm / prune remove boxes; version --json and learn public-suffix wildcards round out scripting support.
  • Egress receipts now report per-host byte volume, and opt-in TLS interception (SSL-bump) is available for scoped deep inspection.

Changed

  • Shell completions install automatically via Homebrew and install.sh (bash + zsh).

Full changelog: v0.6.0...v0.7.0

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 01 Jun 11:31
v0.6.0
15212ef

Multi-box visibility and machine-readable output. See every sandbox on your machine at a glance, get JSON from the inspection commands for scripting and CI, and point boxes at a central egress allowlist.

Added

  • sluice ls lists every built box on this machine - name, status (running/stopped/built), stack, project path, and description - with the box matching your shell's directory marked. Derived from Docker; no extra state to manage.
  • sluice egress [--json] prints what a box actually reached vs. what the firewall blocked - an audit record you can pipe to a file or a collector.
  • --json output for sluice ls and sluice doctor - machine-readable box inventory and posture, for scripting and CI.
  • SLUICE_DESC - an optional one-line box description, shown in sluice ls and sluice doctor.
  • SLUICE_POLICY_URL points a box at a central plain-text allowlist (any http/https/file URL), fetched on the host at run and merged into the box's egress policy. Additive and host-trusted: it can only add allowed hosts, never weaken the sandbox.

Changed

  • README: a "What it looks like" section with real sluice doctor / sluice ls output, status badges, and a one-line note that sluice runs entirely on your machine (the only network call it makes is an opt-out update check).

Full changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 31 May 23:54
v0.5.0
9d89be4

sluice learn --audit - a one-shot, open-egress discovery pass for the egress allowlist.

sluice learn proposes the allowlist from what the firewall blocked, without ever opening egress. --audit covers the one case enforce-mode can't: trusted code whose fetcher aborts on the first blocked host. It runs your command once in a throwaway, credential-stripped container with egress open to all HTTP/HTTPS hosts, then proposes the full allowlist from every host it reached.

Added

  • sluice learn --audit runs SLUICE_RUN_CMD once with egress opened to all HTTP/HTTPS hosts, then proposes the allowlist from everything it reached. Loudly warned and confirm-gated; the audit container is ephemeral and torn down after the run. Enforce-mode learn stays the default.
  • Credential-stripped by design. The audit run forwards no SLUICE_ENV, runs no SLUICE_PRELAUNCH, and mounts no persisted state dirs, so nothing sensitive can leave while egress is open. Non-HTTP ports and IPv6 stay default-DROP throughout. See THREAT_MODEL.md for exactly what it opens and keeps closed.

Changed

  • Slimmer README layout - documented as role-based top-level directories rather than a per-file tree.

Full changelog: v0.4.0...v0.5.0

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 31 May 23:06
v0.4.0
d3a29ab

[0.4.0] - 2026-06-01

Added

  • Supply-chain: sluice lock - write a committable inventory of the built image (every apk + global npm package with version + digest); sluice update re-resolves and relocks. sluice lock --check is a CI drift gate (fails if the image differs from sluice.lock); sluice lock --sbom emits a deterministic CycloneDX 1.5 SBOM for scanners.
  • Agent session persistence (SLUICE_STATE_DIRS) - a coding agent's history, sessions, and auth survive a rebuild, sluice stop, or reboot, via a per-project host store.
  • sluice learn --print - emit the proposed egress allowlist to stdout (review / CI).
  • sluice learn --apply - write the allowlist and rebuild in one step.
  • Nix gallery example + SLUICE_SETUP_ROOT_CMDS (a build-time root hook) - run a reproducible, pinned Nix toolchain inside a sluice, contained at runtime.
  • SLUICE_ALLOW_IPS database-egress demo - reach a fixed-IP, non-HTTP service (Postgres/Redis/MySQL) through the firewall's escape hatch.
  • Codex and Gemini agent presets verified through the harness - all seven presets are now cred-free verified.
  • Update check in sluice version - flags a newer release when one is available (SLUICE_NO_UPDATE_CHECK=1 to disable).

Changed

  • sluice help is grouped into sections (Common / Build & lifecycle / Inspect / Meta).
  • test/verify-runtimes.sh runs the runtime fixtures in parallel.
  • README: an "Updating sluice" section, plus gallery and command-surface docs. The CLI surface is pre-1.0 and may still change before 1.0.

Full changelog: v0.3.1...v0.4.0

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 31 May 17:36
v0.3.1
703fe10

A patch release: the cursor agent preset was broken — now fixed and verified — plus a new agent-verification harness and a security-showcase demo.

Fixed

  • sluice agent cursor was broken. The preset installed @cursor/cli, which 404s on npm — cursor-agent ships via Cursor's own install script, not npm. Switched to the script + a PATH symlink, and verified it installs and runs.

Added

  • Agent-preset verification harness (test/verify-agents.sh + a manual verify-agents.yml). For each preset it builds the image and checks, with no credentials, that the CLI binary installs and runs, every declared API host is reachable through the proxy, a non-allowlisted host is blocked, and the auth env var is forwarded; the live authenticated round-trip is the only cred-gated step (auto-runs if the key is present, else skips). cursor, amp, and opencode are now verified cred-free; opencode's full live round-trip passes too.
  • A firewall/exfil demo (examples/firewall.config.sh) — self-contained and non-server: it reaches an allowlisted host, then is blocked trying to exfiltrate a fake secret to a non-allowlisted host and to a raw IP, surfaced by sluice doctor and the at-exit hint. The threat model, runnable.

Changed

  • Curated the demo gallery into a capability matrix — firewall / strudel / jupyter each show a different slice — and elevated the coding-agent section from a footnote. Trimmed the vite/next/fastapi starters (redundant with sluice init, which scaffolds them) to an init pointer.
  • De-staled the strudel and jupyter demos (/home/node/home/sluice, after the sandbox user rename).

Full changelog: v0.3.0...v0.3.1

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 31 May 16:53
v0.3.0
b1164e9

sluice is a sandboxed, firewalled, non-root container for any project: drop a sluice.config.sh in a directory and run sluice. This release adds a signed base image, fixes a Linux egress bug for rotating-CDN hosts, and verifies rootless Podman.

Added

  • Cosign-signed base image. The generic sandbox core (proxy, firewall, dnsmasq, non-root user) is now published to GHCR as a multi-arch (amd64 + arm64) image, keyless-signed with cosign (GitHub OIDC). Opt a project into building FROM it with SLUICE_BASE_IMAGE=ghcr.io/pyronewbic/sluice-base:0.3.0 instead of rebuilding the core locally — sluice verifies the signature when cosign is installed (SLUICE_REQUIRE_SIGNED=1 to make a missing/failed signature fatal). The image carries no private key: the squid splice cert is generated per-container at runtime. Local-from-core stays the default this release.

Fixed

  • Egress to rotating-CDN hosts on Linux. HTTPS to allowlisted hosts on large rotating IP pools (Google/Akamai/Fastly — e.g. proxy.golang.org, static.crates.io) could fail with an opaque TLS error. squid's transparent-intercept Host-forgery check was rejecting a legitimate host when the client and squid resolved its name to different pool IPs milliseconds apart. A small in-box dnsmasq cache now pins one IP set per session, so both agree and the connection splices through. (Surfaced on Linux only; macOS Docker Desktop's resolver masked it.)
  • Eliminated rm: Permission denied cleanup noise in the test harnesses (chown the mount back to the host uid before teardown).

Changed

  • The non-root sandbox user is now sluice (was node; uid unchanged at 1000). A /home/node/home/sluice symlink keeps existing SLUICE_MOUNTS working. Node + npm remain in the base as the agent runtime.
  • Rootless Podman verified. The acceptance harness now probes rootless Podman in CI; the full egress matrix passes in an unprivileged user namespace, so the route_localnet/disable_ipv6 sysctls and in-netns iptables the proxy needs work rootless too (no rootful requirement).
  • Docs: sluice doctor, the at-exit visible-egress hint, the --HEAD dev stream, and running any language via SLUICE_EXTRA_PKGS + SLUICE_RUN_CMD.

Full changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 31 May 15:01
v0.2.0
d0767a4

Minor release: adds sluice doctor and visible egress denials, plus SLUICE_NAME, and tightens the agent allowlists.

Added

  • sluice doctor - one-shot health check: engine, config, image freshness, effective allowlist, auth env, and the hosts the proxy blocked this run. Self-contained, so it works in the broken states it diagnoses (no engine/config/image, container not running).
  • Visible egress denials - after a default sluice / sluice agent run, a one-line hint lists any not-yet-allowed hosts the proxy blocked (fires even on Ctrl-C), so a silent TLS error no longer hides what to allow.
  • SLUICE_NAME - override the per-project image/container name (defaults to the directory basename).

Changed

  • Agent allowlists scoped to each CLI's documented API-key hosts, dropping browser-only OAuth/sign-in hosts that can't complete headless.
  • Example runtime projects moved to test/fixtures (the sluice init scaffold supersedes them).

Fixed

  • Claude Code v2.x connectivity: allow platform.claude.com, claude.ai, and statsig.com (feature flags).

Full changelog: v0.1.1...v0.2.0