krng (kurung — Indonesian for "to confine") is a lightweight sandbox wrapper for developer tools on Linux. It uses Bubblewrap to confine tools (e.g. AI coding assistants, build systems) to a project directory, isolating them from credentials, SSH keys, GPG sockets, and other sensitive data on the host.
AI coding assistants and other developer tools run arbitrary commands. Sandboxing them limits what they can read or exfiltrate — without the overhead of a full VM or container runtime.
- Linux (kernel 5.4+ recommended)
bwrap— install via your package manager:# Arch sudo pacman -S bubblewrap # Debian/Ubuntu sudo apt install bubblewrap # Fedora sudo dnf install bubblewrap
git clone https://github.com/ivanp/krng
cd krng
# Install to /usr/local/bin (requires write permission)
sudo make install
# Or install to ~/.local/bin (no sudo)
make install-localThe binary is statically compiled (CGO_ENABLED=0) with no runtime dependencies.
krng --versionkrng [WORK_DIR] COMMAND [ARGS...]WORK_DIR— optional absolute path to the project directory. Defaults to the current working directory.COMMAND— the program to run inside the sandbox.
# Run bash in the current directory
krng bash
# Run a tool in a specific project
krng /home/user/myproject claude --dangerously-skip-permissions
# Pass environment variables into the sandbox
KRNG_PASSENV=ANTHROPIC_API_KEY krng claudeAdd the following to ~/.config/krng/config.toml, then run krng claude:
ro_bind = [
"/opt/claude-code", # Claude Code installation
]
bind = [
"~/.claude.json", # Claude Code user config
"~/.claude", # Claude Code session data and MCP servers
]krng claudeAdjust bind entries to match the tools you use inside Claude Code. For example:
bind = [
"~/.claude.json",
"~/.claude",
"~/.dual-graph", # dual-graph MCP state
"~/go", # Go toolchain (for Go-based MCP servers)
"~/.cache/uv", # uv Python package cache
]| Resource | Behavior |
|---|---|
Project directory (WORK_DIR) |
Read-write |
/usr, /bin, /lib, /lib64 |
Read-only |
/etc/resolv.conf, /etc/hosts, etc. |
Read-only (no /etc/passwd secrets) |
/etc/ssl/certs, CA certificates |
Read-only |
/run |
Isolated tmpfs (no GPG/DBUS/keyring sockets) |
/tmp |
Isolated tmpfs (no X11 sockets) — see share_tmp |
/proc, /dev |
Virtualised |
| Network | Shared with host |
HOME |
Isolated tmpfs — only paths listed in bind/ro_bind are accessible |
| SSH keys, GPG keys, credentials | Not accessible |
SSH_AUTH_SOCK, DBUS_SESSION_BUS_ADDRESS, AWS_*, GH_TOKEN, etc. |
Cleared (--clearenv) |
krng uses two levels of TOML configuration:
~/.config/krng/config.toml (or $XDG_CONFIG_HOME/krng/config.toml)
Created automatically on first run. Settings here apply to every invocation.
# Pass API keys into the sandbox
passenv = [
"ANTHROPIC_API_KEY",
"OPENAI_API_KEY",
]
# Pass the host PATH so tools in custom directories (e.g. ~/.local/bin, ~/.dual-graph)
# are found inside the sandbox. Without this, the sandbox uses a minimal system PATH.
# passenv = ["PATH"]
# Read-only bind mounts
ro_bind = [
"~/.config/gh", # GitHub CLI config
]
# Read-write bind mounts
# bind = [
# "/var/run/docker.sock",
# ]
# Disable --new-session (re-enables Ctrl+Z / job control)
# new_session = false
# Share host /tmp (exposes X11/Wayland sockets — off by default)
# share_tmp = trueWORK_DIR/krng.toml
Per-project config is intentionally restricted to behavior flags only (new_session, share_tmp). Bind mounts and env pass-through are not allowed here — those require the global config, which only you control.
⚠ Security:
krng.tomlis loaded from the project directory before sandboxing. A malicious repository can use it to change sandbox behavior. Review it before running krng in an untrusted repository.
# Disable --new-session to re-enable Ctrl+Z / job control.
# new_session = false
# Share host /tmp (exposes X11/Wayland sockets).
# share_tmp = true- Bind mounts and passenv (
passenv,ro_bind,bind): global config only. Project config cannot declare these. - Booleans (
new_session,share_tmp): project value overrides global if set; global value used otherwise.
| Variable | Effect |
|---|---|
KRNG_PASSENV |
Comma-separated env vars to pass through |
KRNG_SHARE_TMP |
1 = share host /tmp; 0 = isolate |
KRNG_NEW_SESSION |
0 = disable --new-session; 1 = enable |
krng.toml in a project directory you did not write can change sandbox behavior. Review krng.toml before running krng in an untrusted repository, just as you would review a Makefile or package.json.
krng is not a complete security boundary. It reduces attack surface but does not prevent all possible escapes. For stronger isolation, consider a VM.
--new-session is enabled by default. It detaches the sandboxed process from the controlling TTY, mitigating CVE-2017-5226 (TIOCSTI injection) and CVE-2025-37814. Disable it with new_session = false if you need Ctrl+Z / fg job control inside the sandbox.
KRNG_ACTIVE must not be set in shell profiles (~/.bashrc, ~/.zshrc, etc.). If set outside a sandbox, sandboxing is skipped entirely and the command runs with the full parent environment.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Usage error (no arguments) |
| 2 | Invalid arguments or command not found |
| 3 | Config error (parse failure or unreadable config directory) |
| 4 | Invalid WORK_DIR (protected path or unresolvable symlink) |
| 6 | bwrap not found or exec failed |
| 7 | Error constructing sandbox arguments |
make build # compile
make test # run tests with race detector
make check # vet + test
make clean # remove build artifacts- Claude Dev Container — official Docker-based dev container for Claude Code; full container isolation
- cco — runs Claude Code in a Docker container with automatic project mounting
- claudebox — Docker-based sandbox with a curated development toolchain for Claude Code
krng differs in that it uses Bubblewrap (no Docker/container runtime required) and has zero overhead — it's a thin namespace wrapper, not a VM or container image.
MIT — see LICENSE.