Tools to monitor and sandbox processes on Linux. While primarily developed to supervise AI coding agents, all tools work with any process.
- Monitoring — bpftrace scripts that trace what a process and all its descendants are doing (exec, file, network, suspicious ops) using kernel tracepoints, kprobes, and uprobes. Requires Linux with BTF support (
CONFIG_DEBUG_INFO_BTF=y), bpftrace >= 0.21. - Sandboxing — a bubblewrap wrapper that jails processes with configurable filesystem, command, and network restrictions. Requires bwrap, Python 3.6+, PyYAML.
Example configuration files for popular AI coding agents are provided in the confs/ directory.
- Key tools
- monitor-process.sh — all-in-one bpftrace monitoring wrapper
- jail-process.py — bubblewrap sandboxing / jailing
- Individual bpftrace scripts
- Configuration files
- Sandbox profiles
The main entry point for monitoring. Launches or attaches to any process and runs all bpftrace scripts in parallel. Traces are written to a log file (not the terminal). Supports selective tracer disabling and file-tracer output filtering.
# Run mode — launch a command and trace it
./monitor-process.sh -- <COMMAND> [ARGS...]
# Attach mode — trace an already-running process
./monitor-process.sh -p <PID>
# With a config file (e.g. for Claude Code)
./monitor-process.sh -c confs/monitor-claude.conf -- claude --resume
# Disable specific tracers
./monitor-process.sh -EN -- my-program run
# Follow traces in real time from another terminal
tail -f <log-file>
See ./monitor-process.sh -h for all options.
Wraps bubblewrap to sandbox any process with least-privilege restrictions. Uses YAML profiles to configure what the process can access.
What it restricts:
- Filesystem — only explicitly listed paths are mounted (read-only or read-write)
- Commands — only whitelisted binaries are available;
/usr/binis NOT mounted wholesale - Namespaces —
--unshare-allby default (PID, mount, network, user, IPC, UTS, cgroup) - Network — denied by default, must be explicitly enabled per profile
- Environment — cleared and rebuilt from config only
# Dry-run — inspect the generated bwrap command
./jail-process.py -c confs/jail.yaml -p claude --dry-run -- claude
# Run a process inside the sandbox
./jail-process.py -c confs/jail.yaml -p claude -- claude
# Add extra mounts from the command line
./jail-process.py -c confs/jail.yaml -p claude --rw ~/myproject --ro /opt/data -- claude
See ./jail-process.py -h for all options.
Features:
- Profiles defined in YAML (
confs/jail.yaml), one per process/agent ~expansion in all path fields for portable configs- Automatic script dependency scanning — shell wrapper shebangs and
exectargets are resolved and bound - Binaries are bound at all their paths (canonical,
which, and realpath) so they work regardless of how they're referenced --dry-runprints a readable, copy-pasteable bwrap command--ro/--rwCLI flags to add extra mounts without editing the config
Monitors sub-processes spawned by the target process. Logs every execve call with the full command line.
sudo bpftrace trace-execs.bt <PID>
Monitors outbound network activity: TCP connects, DNS lookups (UDP port 53), data transfer (TX/RX for TCP and UDP), and hostname resolution via getaddrinfo. When a hostname is resolved before a connection, subsequent TCP events display the hostname alongside the IP address. Consecutive TCP send/receive events for the same connection are aggregated into a single line showing total bytes and call count.
sudo bpftrace trace-netcalls.bt <PID>
Monitors file operations: opens (read/write/create), reads, writes, directory creation, deletes, renames, chmod, and chown. Tracks fd-to-filename mappings so that read/write syscalls display the file path and byte count.
sudo bpftrace trace-files.bt <PID>
Monitors suspicious or potentially dangerous operations:
- Credential/secret access — opening SSH keys, GPG keyrings, Cloud credentials,
.env, token/secret files, etc. - Privilege escalation —
setuid/setgid/setresuid/setresgid,capset - Persistence mechanisms — writing to crontabs, systemd unit files, shell startup files (
.bashrc,.zshrc, etc.) - System manipulation —
ptrace(process injection),mount/umount, kernel module loading, hostname changes - Covert execution —
memfd_create(fileless execution), raw socket creation - Listening sockets / reverse shells —
bind,listen,accept/accept4 - Cross-process memory access —
process_vm_readv/process_vm_writev - Namespace / sandbox escape —
unshare,chroot,pivot_root - Code injection / anti-forensics —
mprotectwith PROT_EXEC,prctlPR_SET_DUMPABLE=0,seccomp,personality,userfaultfd - Symlink / hardlink attacks —
symlinkat,linkat - Credential keyring access —
keyctl - Destructive actions —
reboot,killoutside watched process tree - Permission manipulation —
chmodwith setuid/setgid bits
sudo bpftrace trace-suspicious.bt <PID>
monitor-process.sh options can be set via CLI flags, environment variables, or a config file sourced with -c. Example config files for popular AI coding agents are provided in the confs/ directory:
| Config file | Tool |
|---|---|
confs/monitor-claude.conf |
Claude Code |
confs/monitor-codex.conf |
OpenAI Codex CLI |
confs/monitor-aider.conf |
Aider |
confs/monitor-cline.conf |
Cline |
confs/monitor-goose.conf |
Goose |
confs/monitor-continue.conf |
Continue |
confs/monitor-openhands.conf |
OpenHands |
Precedence: defaults < env vars < config file < CLI options.
Pre-configured profiles for popular AI coding agents are provided in confs/jail.yaml. Any process can be jailed by adding a new profile to this file.
| Profile | Tool | Agent state directory |
|---|---|---|
claude |
Claude Code | ~/.claude, ~/.claude.json |
codex |
OpenAI Codex CLI | ~/.codex |
aider |
Aider | ~/.config/aider, ~/.aider.conf.yml |
cline |
Cline | ~/.cline |
goose |
Goose | ~/.config/goose |
continue |
Continue | ~/.continue |
openhands |
OpenHands | ~/.openhands |
Each profile mounts shared libraries (/usr/lib, /lib, /lib64) read-only, the agent's state directory read-write, and whitelists a minimal set of commands. Edit ~/project in the config to point at your working directory.