Commit Graph

60 Commits

Author SHA1 Message Date
mrtoth 1165aea9aa Stop overriding the sandbox hostname
Setting --hostname sandbox inside the UTS namespace was purely cosmetic
(a label for interactive shells) and provided no isolation beyond what
--unshare-uts already gives. It also caused codex to hang for ~5s on
startup: glibc resolved the unknown "sandbox" name via systemd-resolved
and waited through two DNS retry timeouts before giving up.

Dropping the override lets the sandbox inherit the host's hostname,
which already resolves locally, eliminating the stall.
2026-04-27 21:08:05 +02:00
mrtoth 105eafef2e Move codex home 2026-04-27 09:32:39 +02:00
mrtoth af731a107f Add pi agent profile 2026-04-27 08:38:15 +02:00
mrtoth 6e81866226 Default to whitelist mode and parallelize tests
Flips the default sandbox mode from blacklist to whitelist and
replaces the global RUST_TEST_THREADS=1 with a targeted RwLock
that only serializes blacklist sandboxes against tests mutating
glob-matching host paths. A new Sandbox newtype acquires the
guard automatically when --blacklist is in args.
2026-04-27 08:18:41 +02:00
mrtoth c77dbc10c3 Implement profile inheritance 2026-04-26 23:58:21 +02:00
mrtoth 7f9b21ef4f Organize test code better 2026-04-25 15:10:42 +02:00
mrtoth 0ea83b2af0 Implement extra-config option 2026-04-24 20:09:27 +02:00
mrtoth a9f5593f03 Extract claude and codex configs into separate profiles 2026-04-24 08:31:37 +02:00
mrtoth 7c9375cd94 Canonicalize blacklist overlay paths to skirt /var/run symlink 2026-04-23 18:47:27 +02:00
mrtoth 862feada05 Document hardening, network default, and profile merge rules 2026-04-22 23:14:51 +02:00
mrtoth 6933deb441 Document config-example.toml as the canonical deployed config
Makes it clear that the example config is meant to be symlinked into
$XDG_CONFIG_HOME/agent-sandbox/ so it stays in sync with the repo.
2026-04-22 22:43:46 +02:00
mrtoth 972747a891 Whitelist terminal identity and pager env vars
Without TERM_PROGRAM/TERM_PROGRAM_VERSION, Claude Code and similar TUIs
can't detect the host emulator and lose capability-gated features like
Shift+Enter. Also pass through LS_COLORS, LESS*, MANPAGER, MANPATH, etc.
so interactive UX matches the host.
2026-04-22 22:34:01 +02:00
mrtoth 1e9b7735a8 Mount agent-config repo ro in example config 2026-04-22 21:51:15 +02:00
mrtoth 305ac9d927 Accept SRC:DST remap syntax in --ro/--rw 2026-04-22 21:51:00 +02:00
mrtoth 06bb638737 Document all config options with commented examples 2026-04-22 20:55:07 +02:00
mrtoth 494da52fc6 Replace setenv with env list supporting host passthrough 2026-04-22 20:47:01 +02:00
mrtoth 76c5be0e72 Fix misinformation in seccomp comments 2026-04-13 17:03:38 +02:00
mrtoth 7b7294d94e Follow symlinks when classifying sensitive paths in blacklist mode 2026-04-13 16:49:42 +02:00
mrtoth bd1f938f54 Block CLONE_NEWUSER in seccomp argument filter on clone
Prevents sandboxed processes from creating user namespaces to gain fake
root, the standard entry point for kernel privilege-escalation exploits.
Matches Docker and Podman's default seccomp policy.

clone3 remains fully denied (not in the allowlist) so glibc falls back
to clone where this argument filter applies.

Also switches hand-written ioctl constants to libc::{TIOCSTI,TIOCLINUX}.
2026-04-13 16:46:15 +02:00
mrtoth 0d0682b04e Replace --new-session with seccomp TIOCSTI/TIOCLINUX filter 2026-04-12 15:58:50 +02:00
mrtoth 8f30d28965 Let --rw override --ro on a child path by emitting ro binds first 2026-04-12 14:36:07 +02:00
mrtoth 327c2933e7 Add README note about ubuntu apparmor woes with bubblewrap 2026-04-08 09:27:40 +02:00
mrtoth 25f0037aab Filter environment variables in both sandbox modes
Whitelist mode now clears the parent env and re-adds a small allowlist
(identity, terminal, locale, proxy, non-GUI XDG, vendor prefixes).
Blacklist mode strips cloud credentials, backup passphrases, dangling
socket pointers, and anything matching *_TOKEN, *_SECRET, *_PASSWORD,
*_PASSPHRASE, *_API_KEY, *_PRIVATE_KEY, *_CLIENT_SECRET; vendor prefix
carve-outs keep ANTHROPIC_API_KEY and friends.

Users can override via --setenv KEY=VALUE and --unsetenv KEY (and the
corresponding TOML keys), or opt out of the built-in policy entirely
with --no-env-filter.
2026-04-08 09:22:11 +02:00
mrtoth 12644ae31e Apply a seccomp-BPF syscall allowlist by default
Derived from Podman's default profile, stripped of capability-conditional
rules (we never grant capabilities), argument filters, and the explicit
EPERM block. Dangerous syscalls (mount, unshare, ptrace, bpf,
perf_event_open, io_uring_*, keyctl, kexec_*, ...) fall through to the
default ENOSYS action, which also keeps glibc's clone3 -> clone fallback
working. x86_64 and aarch64 are supported; other archs error out.

Toggle with --seccomp / --no-seccomp or seccomp = <bool> in config.
2026-04-08 08:34:34 +02:00
mrtoth 5f3b139457 Drop redundant trim() before split_whitespace()
split_whitespace already skips leading and trailing whitespace, so the
trim() call is redundant and trips clippy::trim_split_whitespace.
2026-04-08 00:23:15 +02:00
mrtoth 8010e9102e Allow disabling boolean flags from the CLI
Pair --hardened, --dry-run, and --unshare-net (renamed from --no-net)
with negation counterparts so a CLI invocation can override a truthy
config-file or profile value.
2026-04-08 00:22:50 +02:00
mrtoth 17f0e84005 Allow setting entrypoint from CLI 2026-04-07 18:02:03 +02:00
mrtoth 83bd4305c7 Bind symlinked rw/ro paths at the user-written destination
Canonicalizing rw/ro paths in the config layer resolved symlinks before
the sandbox was built, so a symlinked entry only appeared at its
target's location -- never at the path the user wrote. Stop
canonicalizing rw/ro at the config layer and instead resolve only the
source side of the bind in sandbox.rs.
2026-04-07 17:45:38 +02:00
mrtoth f0711f2894 Ship an example config file 2026-04-07 15:10:10 +02:00
mrtoth cab0eb74d7 Error out if no entrypoint or command is passed (drop claude default) 2026-04-04 10:19:58 +02:00
mrtoth 062ddab5f8 Add entrypoint option 2026-04-04 10:16:57 +02:00
mrtoth 8ecba5d6dc Add option to pass through arguments to brwap, use shlex for dry-run 2026-04-04 08:51:08 +02:00
mrtoth 8958f79ece Document and expand test coverage of config file feature 2026-04-04 08:51:08 +02:00
mrtoth db60fb9ddb Reject unknown config keys 2026-04-01 23:51:47 +02:00
mrtoth c7c4c673cb Add mask option to hide paths/files from sandbox 2026-04-01 23:19:08 +02:00
mrtoth 0119834d5a Implement config file parsing and precedence with CLI 2026-03-31 01:22:08 +02:00
mrtoth f1d7a14b8d Ensure root filesystem is always read-only inside sandbox
Whitelist mode's implicit bwrap root was a writable tmpfs, letting the
sandboxed process create files and directories anywhere not covered by
an explicit ro mount. This was not an issue in blacklist mode due to
--ro-bind / / covering that case.

This patch adds --remount-ro / before any other mount to make the base
layer read-only in both modes.
2026-03-29 16:50:59 +02:00
mrtoth 389e38a800 Add CLAUDE.md and AGENTS.md with build rules and pitfalls 2026-03-25 23:59:37 +01:00
mrtoth 99f9395c10 Move require_run_user to lib.rs and make blacklist module private 2026-03-25 23:54:35 +01:00
mrtoth 5fc7eb3c11 Consolidate whitelist mode setup into add_whitelist_mode 2026-03-25 23:43:48 +01:00
mrtoth 960b034a80 Run integration tests serially to avoid /tmp race conditions 2026-03-25 23:43:26 +01:00
mrtoth b200be9490 Add README with security model documentation 2026-03-25 23:13:16 +01:00
mrtoth d79563d948 Add integration test for /dev/input/ being hidden in blacklist mode 2026-03-25 23:02:24 +01:00
mrtoth 167439c156 Add fish/nushell history and /tmp leaks to SENSITIVE_PATHS 2026-03-25 23:00:52 +01:00
mrtoth 6349709024 Add container, WM, package manager, and database sockets to SENSITIVE_PATHS 2026-03-25 22:58:12 +01:00
mrtoth d3f8986b77 Sort dirs before files in resolve_overlays
Glob results within a SENSITIVE_PATHS entry could return files before
their parent directory. When that happens the file gets a null-bind
while its siblings remain visible, because the parent hasn't been added
to tmpfs_dirs yet. Sorting dirs first removes this implicit ordering
dependency.
2026-03-25 22:54:56 +01:00
mrtoth 82f84247f1 Rework handling of /run and ${RUNUSER} in blacklist mode 2026-03-25 22:48:39 +01:00
mrtoth 0bd91ffad2 Add /sys to whitelist mode 2026-03-25 22:22:35 +01:00
mrtoth dccf2309a5 Add --new-session to bwrap invocation 2026-03-25 22:15:21 +01:00
mrtoth 9f82ca21ee Add /dev/input/ to SENSITIVE_PATHS for blacklist mode 2026-03-25 22:00:32 +01:00