ARAPUCA(1)

๐Ÿ“ฆ
version 0.2.8 ยท 2 versions
, in fedora 43

๐Ÿซถ arapuca โ€” from the Arapuca Manual, section 1 ๐Ÿซถ

okay bestie, sit down, hydrate, and let me tell you about arapuca. it's giving sandbox, it's giving kernel-enforced isolation, it's giving "your untrusted code cannot hurt me" ๐Ÿ’…


๐ŸŒธ NAME ๐ŸŒธ

arapuca โ€” sandbox a command with kernel-enforced isolation. that's it, that's the whole vibe.


โœจ SYNOPSIS โœจ

arapuca run [flags] -- command [args...]

arapuca -h | --help

arapuca -V | --version

note the -- bestie. it is not optional. the -- is the main character here, it's what separates your flags from the command. ๐ŸŽ€


๐Ÿ’– DESCRIPTION ๐Ÿ’–

arapuca run launches command in a process-level sandbox with user-friendly CLI flags. it uses the library's platform abstraction so it's cross-platform, no cap: Landlock + seccomp on Linux, Seatbelt on macOS, AppContainer on Windows. three platforms, one slay. ๐ŸŒˆ

there's also the internal wrapper path โ€” arapuca -- command. that one applies sandbox restrictions to the current process, then replaces itself with command via execve(2). it's configured via environment variables. it's used internally by the library as a subprocess wrapper, so direct CLI invocations require ARAPUCA_WRAPPER=1 to be set by the library. unrecognized subcommands or flags are rejected. ๐Ÿšซ

on Linux, arapuca enforces Landlock filesystem restrictions, seccomp BPF syscall filtering, POSIX resource limits, and sets PR_SET_PDEATHSIG so the subprocess gets killed if the parent dies. it's giving loyal, it's giving no orphans. ๐Ÿ”ฅ

on macOS, arapuca enforces POSIX resource limits only โ€” filesystem and network restrictions are applied by the caller via sandbox-exec(1). so like, it's doing its part, but the caller's doing the rest. teamwork. ๐Ÿซถ

the sandbox is fail-closed: if any restriction fails to apply, arapuca exits non-zero and the target command never runs. literally never. no half-sandbox, no "oops we tried". periodt.

all ARAPUCA_* environment variables are stripped before exec so the sandboxed process cannot inspect its own configuration. sneaky-proof. ๐Ÿ™ˆ non-ARAPUCA variables (e.g., AGENT_NETWORK_PROXY) are preserved, so your other stuff survives the cleanse.


๐Ÿ’… OPTIONS (arapuca run) ๐Ÿ’…

  • -v path[:ro] โ€” allow access to path. read-write by default; append :ro for read-only. repeatable. paths must be absolute. default system paths (/usr, /lib, /bin, /etc/ssl, /tmp, device nodes) are readable. only the private per-task temp dir is writable by default. /proc, /sys, and blanket /dev are NOT included by default. use -v /tmp to grant write access to all of /tmp. ๐Ÿ‘‘
  • --cwd path โ€” set the working directory for the sandboxed process. the path must be absolute, must exist, must be a directory, and must be within a mounted path (default or -v). symlinks are resolved before the containment check. useful for programmatic callers that need to set the working directory without shell wrappers. very "i know what i'm doing" of you. โœจ
  • --env KEY=VALUE โ€” pass an environment variable to the sandboxed process. dangerous variables (LD_PRELOAD, ARAPUCA_*, DYLD_*, interpreter injection vectors) are rejected. sandbox-managed variables (HOME, TMPDIR, PATH, LANG) cannot be overridden. repeatable. sorry bestie, PATH is not yours to change. ๐Ÿ˜ญ
  • --timeout N โ€” kill the process after N seconds. sends SIGTERM first, then SIGKILL after a 5-second grace period. N must be greater than 0. it's polite, then it's not. ๐Ÿ’€
  • --memory N โ€” memory limit in megabytes. enforced via cgroups v2 on Linux, RSS polling on macOS, Job Objects on Windows.
  • --cpus N โ€” CPU limit as a percentage of a single core. 200 means 2 cores. math but make it fashion. ๐Ÿงฎ
  • --pids N โ€” maximum number of PIDs (cgroups v2 on Linux, Job Objects on Windows).
  • --task-id NAME โ€” identifier for cgroup directory and audit events. must match [a-zA-Z0-9-]+, max 128 characters. defaults to run-pid.
  • --seccomp mode โ€” seccomp BPF filter profile. strict (default) blocks AF_INET, symlink, memfd_create, io_uring, and other syscalls โ€” designed for untrusted code. baseline blocks only sandbox-escape syscalls (ptrace, mount, namespace ops, kernel modules, bpf) and adds /proc + /sys read access โ€” designed for trusted-but-isolated applications like Claude Code that need full runtime capabilities while being confined by Landlock + netns. pick your fighter. ๐ŸฅŠ
  • --allow-host host:port โ€” allow HTTPS traffic to host:port via a CONNECT proxy tunnel. repeatable. supports exact match (api.example.com:443) and wildcard suffix match (*.googleapis.com:443 โ€” matches the domain itself and any subdomain). when specified, the sandboxed process runs in a network namespace with no direct network access. a CONNECT proxy on the host network tunnels traffic only to listed hosts. DNS resolution happens in the proxy with IP validation (loopback, RFC 1918, CGNAT, link-local, and cloud metadata addresses are rejected to prevent DNS rebinding SSRF). Linux only. ๐Ÿง
  • -t, --tty โ€” allocate a pseudo-terminal (PTY) for the sandboxed process. enables interactive programs (shells, editors, TUI applications) that require a terminal. requires stdin and stdout to be a terminal. the TERM environment variable is forwarded from the host (sanitized). for the girls who need a real terminal, not a pipe. ๐ŸŽ€

๐ŸŒˆ ENVIRONMENT (internal wrapper) ๐ŸŒˆ

  • ARAPUCA_WRAPPER โ€” internal sentinel. must be set to 1 by the library when invoking the wrapper path. direct invocations without this variable are rejected. stripped before exec. it's the secret handshake. ๐Ÿค

the following variables configure the internal wrapper path. they are not used by arapuca run (which uses CLI flags instead). okay so two different worlds, don't mix them up.

  • ARAPUCA_READ_PATHS โ€” colon-separated list of paths the subprocess may read. each path and everything below it is readable.
ARAPUCA_READ_PATHS=/usr:/lib:/lib64:/bin:/etc:/dev
  • ARAPUCA_WRITE_PATHS โ€” colon-separated list of paths the subprocess may read and write.
ARAPUCA_WRITE_PATHS=/tmp/workspace
  • ARAPUCA_RLIMIT_AS โ€” maximum virtual memory size in bytes. enforced via setrlimit(2) (RLIMIT_AS). set to 0 or omit to leave unlimited.
on Apple Silicon, RLIMIT_AS should not be set โ€” macOS aggressively maps virtual memory and setting this limit causes immediate SIGKILL. ๐Ÿ’€ seriously, do not.
  • ARAPUCA_RLIMIT_NPROC โ€” maximum number of processes for the user. enforced via setrlimit(2) (RLIMIT_NPROC). set to 0 or omit to leave unlimited.
  • ARAPUCA_RLIMIT_CPU โ€” maximum CPU time in seconds. enforced via setrlimit(2) (RLIMIT_CPU). the kernel sends SIGXCPU when the soft limit is reached and SIGKILL at the hard limit. set to 0 or omit to leave unlimited. two warnings, then the hammer. ๐Ÿ”จ
  • ARAPUCA_RLIMIT_FSIZE โ€” maximum file size in bytes. enforced via setrlimit(2) (RLIMIT_FSIZE). writes that would exceed the limit receive SIGXFSZ. set to 0 or omit to leave unlimited.

๐Ÿ”ฅ EXIT STATUS ๐Ÿ”ฅ

  • 0 โ€” the target command exited successfully. slay. โœจ
  • 1 โ€” usage error (unrecognized subcommand or flag, missing ARAPUCA_WRAPPER sentinel, no -- separator, command not found, or sandbox setup failed). a diagnostic is printed to stderr. ๐Ÿ˜ญ
  • >1 โ€” the target command exited with a non-zero status. the exit code is passed through. we don't hide your failures, we just relay them.
  • 125 โ€” sandbox infrastructure error (arapuca run only). invalid flags, sandbox setup failure, or CONNECT proxy failure.
  • 137 โ€” the target command was killed by SIGKILL (e.g., parent died and PR_SET_PDEATHSIG fired, cgroup OOM kill, or timeout SIGKILL). ๐Ÿ’€
  • 143 โ€” the target command was killed by SIGTERM (e.g., timeout fired). the gentler goodbye. ๐Ÿซถ

๐Ÿ‘‘ SECURITY ๐Ÿ‘‘

๐Ÿง Linux

on Linux (kernel 5.13+), arapuca enforces:

  • Landlock โ€” restricts filesystem access to the paths listed in ARAPUCA_READ_PATHS and ARAPUCA_WRITE_PATHS. all other paths are inaccessible. supports ABI versions 1 through 6.
  • Seccomp BPF โ€” installs a syscall filter with two tiers:
    • KILL_PROCESS: ptrace, mount, chroot, unshare, setns, clone3, memfd_create, io_uring, bpf, kexec, kernel module loading.
    • EPERM: symlink, link, socket(AF_INET), socket(AF_INET6), perf_event_open.
    • socket(AF_UNIX) is allowed โ€” it is needed for IPC with the host (JSON-RPC control socket, LLM proxy). bestie privileges. ๐Ÿซถ
  • PR_SET_NO_NEW_PRIVS โ€” set before Landlock and seccomp. prevents privilege escalation via setuid binaries.
  • PR_SET_PDEATHSIG โ€” sends SIGKILL to the subprocess if the parent process dies. prevents orphaned sandboxed processes. no abandoned children in this household. ๐Ÿ’…

๐ŸŽ macOS

on macOS, arapuca enforces only POSIX resource limits. filesystem and network restrictions are applied externally by sandbox-exec(1) using a Seatbelt profile generated by the arapuca library. teamwork, again.

๐ŸŒˆ Both Platforms

  • POSIX resource limits โ€” RLIMIT_AS, RLIMIT_NPROC, RLIMIT_CPU, and RLIMIT_FSIZE are set as both soft and hard limits, so the subprocess cannot raise them. locked in, no takebacks. ๐Ÿ”’
  • Environment stripping โ€” all ARAPUCA_* variables are removed. the subprocess cannot discover its own sandbox configuration. what config? never heard of her. ๐Ÿ™ˆ

๐Ÿฆ‹ EXAMPLES ๐Ÿฆ‹

โœจ arapuca run

run a command with default sandboxing:

arapuca run -- /bin/echo hello

grant read-only access to a project directory:

arapuca run -v /home/user/project:ro -- ls /home/user/project

sandbox a Claude Code agent with selective HTTPS access:

arapuca run \
  -v /home/user/repo \
  --allow-host us-east5-aiplatform.googleapis.com:443 \
  --allow-host oauth2.googleapis.com:443 \
  --env VERTEXAI_PROJECT=my-project \
  --timeout 600 --memory 3072 \
  -- claude --bare -p --model claude-sonnet-4-6

interactive PTY session inside the sandbox:

arapuca run -t \
  -v /home/user/project:ro \
  --seccomp baseline \
  -- /bin/bash

๐Ÿงš Internal wrapper (arapuca --)

run a Python script with read access to system paths and write access to a workspace directory (requires ARAPUCA_WRAPPER=1):

ARAPUCA_READ_PATHS=/usr:/lib:/lib64:/bin:/etc:/dev \
ARAPUCA_WRITE_PATHS=/tmp/workspace \
arapuca -- python3 agent.py

run a command with resource limits (2 GB memory, 256 processes, 1 hour CPU, 1 GB max file size):

ARAPUCA_RLIMIT_AS=2147483648 \
ARAPUCA_RLIMIT_NPROC=256 \
ARAPUCA_RLIMIT_CPU=3600 \
ARAPUCA_RLIMIT_FSIZE=1073741824 \
arapuca -- ./run-tests.sh
the internal wrapper requires ARAPUCA_WRAPPER=1 โ€” direct CLI invocations are rejected. use arapuca run instead. fr fr, just use arapuca run. ๐Ÿซถ

๐ŸŒŸ SEE ALSO ๐ŸŒŸ

landlock(7), seccomp(2), setrlimit(2), sandbox-exec(1), prctl(2), execve(2), unshare(1)


๐Ÿ’œ AUTHORS ๐Ÿ’œ

Sergio Correia <scorreia@redhat.com> โ€” the icon who built this. ๐Ÿ‘‘


and that's the whole page, bestie โ€” this was arapuca from the Arapuca Manual, section ARAPUCA(1). go forth, sandbox responsibly, and remember: fail-closed or it didn't happen. ๐Ÿ’–โœจ๐ŸŽ€๐Ÿฆ‹๐ŸŒธ๐Ÿ’…๐Ÿซถ

๐Ÿ“ฆ where this page comes from
  • fedora 43: arapuca 0.2.8-1.fc43 ยท Apache-2.0 AND MIT AND (Apache-2.0 OR BSD-3-Clause) AND (Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT) AND (MIT OR Apache-2.0 OR LGPL-2.1-or-later)
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms