Commit Graph

50 Commits

Author SHA1 Message Date
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
mrtoth ada9da7ae7 Reject empty HOME envvar 2026-03-20 21:43:08 +01:00
mrtoth 4112288a30 Ensure passing relative paths to CLI works 2026-03-20 21:36:55 +01:00
mrtoth 94535b20d3 Fix blacklist bind mount order 2026-03-20 21:02:48 +01:00
mrtoth 826c6d5531 Add ~/.claude.json to agent paths and use --bind-try 2026-03-20 20:41:24 +01:00
mrtoth 50dafb4c37 Fix read-only /dev, /proc, /tmp, /var/tmp, /run in blacklist mode 2026-03-20 20:40:57 +01:00
mrtoth c8e0d4813a Use --ro-bind-try for system files in whitelist mode 2026-03-20 19:29:53 +01:00
mrtoth b4b94856ac Skip run_user overlay when runtime dir is unknown 2026-03-20 19:29:43 +01:00
mrtoth 9da043a70e Remove redundant /etc/ssh/* glob entry 2026-03-20 19:29:38 +01:00
mrtoth ba885b7dd6 Ensure test file is cleaned up in cwd_is_writable test case 2026-03-20 18:52:03 +01:00
mrtoth bf53d92d49 Initial commit 2026-03-20 18:40:08 +01:00