Sandbox any program to only what you allow
Run any program so it changes only the folders you give it, reaches only what you allow, and never reads Link's settings. Every Link agent runs in it, and so can anything else.
lnk sandbox ready # whether the sandbox can run here, and on Linux what it needs
# a shell that can change only this folder
lnk sandbox run --write . -- bash
# the internet, but nothing on this machine or its network
lnk sandbox run --internet-host '*' -- curl -sI https://example.com
# a sandbox written down, below: only what its file opens
lnk sandbox run --spec app.toml -- node app.js
lnk sandbox check --write . # try from inside what it should not allow
lnk sandbox log # every call on the proxies of the sandboxesWhat it needs
You need a Mac, whose Seatbelt is built in, or Linux with bubblewrap. The
sandbox plugin comes with every harness, and lnk plugin add sandbox
installs it alone. It's free and needs no account.
Run a program
How to run a program in the sandbox, with only the folders you give it, or with all of it written down in a file.
Run a program in the sandbox
The program reads the system's programs and libraries, and nothing else
unless you open it. It has no network. Its environment is cleared, so no
tokens or SSH_AUTH_SOCK from your shell reach it. run exits with the
command's status.
lnk sandbox run --write ~/Projects/site -- npm run build
lnk sandbox run --read ~/Documents/reports --write . -- python3 summarize.py
lnk sandbox run --read '~' --port 5432 -- ./toolIts arguments
Arguments after -- reach the program unchanged, including option names
also used by the sandbox's internal launchers.
--write and --read
--write <dir> is a folder it may read and write, and --read <dir>
one it may only read. Both repeat, and --read '~' reads your whole
home folder except Link's settings. --port <port> lets it connect to a
port on this machine's loopback.
--hide
--hide <dir> closes a folder to it even then, except for the --write
and --read folders inside it. Agents' folders in ~/Link/Agents, and
what agents that left kept in ~/Link/History, are always hidden this
way.
Every flag is a key
Every flag is a key of a spec, the file the next section writes. lnk sandbox permissions lists each section and its flags, and lnk sandbox run --help describes them.
Describe a sandbox in a file
A spec is a TOML file whose sections are the sandbox's only grants:
[files], [internet], [lan], [localhost], [tools], [browser]
and [commands]. A section left out stays closed, so a spec with no
sections reads none of your files, reaches no network and runs no
program. The spec
lists every key and what it takes.
lnk sandbox spec --write ~/code/app --internet-host '*' --command node > app.toml # a spec to start from
# shows what a new spec opens, and asks
lnk sandbox run --spec app.toml -- node app.js
# without asking
lnk sandbox run --spec app.toml --yes -- node app.js
lnk sandbox check --spec app.toml # try from inside what it should not allow
lnk sandbox spec --spec app.toml # the spec, paths absolutename = "app"
version = 1
[files]
write = ["~/code/app"]
[internet]
hosts = ["registry.npmjs.org", "api.openai.com"]
[commands]
allow = ["sh", "node", "npm"]Asked first
A spec can come from anyone, so one you haven't run here, or one that
opens something different now, shows what it opens and asks first.
--yes answers for you. A flag beside --spec replaces that key of the
file's, except --hide, which adds to it.
What it can't open
A spec can't open Link's settings, agents' folders, or anything that would let a program reach outside the sandbox (each).
Let it commit
At the top of each folder it writes, a project's dot files that run
outside the sandbox, such as .git, .envrc, .vscode and .idea,
are read only (the full list).
So git status, diff and log work, and a commit, git config or a
new hook needs --write-dot-files to name the folder, or [files] write_dot_files in a spec.
# reads the repository, cannot change it
lnk sandbox run --write . -- git status
# commits
lnk sandbox run --write . --write-dot-files . -- git commit -qam fixWhy they're read only
What's written there would run as you, outside the sandbox, the next
time you run git, cd into the folder or open it in your editor.
Only the top
Only the top of each folder is kept read only, so a repository the program clones or makes in a folder inside is its own to write. Give it the project's folder, not the one holding all your projects.
Choose what it can reach
The programs it runs, the hosts, machines and models it reaches, the
tools it calls and the pages it opens, each a flag of lnk sandbox run
and a key of a spec: Choose What It Can Reach.
Answer what a sandbox asks
A call that asks you first, such as a tool's or a page to open, shows a dialog on this computer's screen, asks on the terminal the sandbox started from, with a four-letter code to type back, and for an agent's sandbox asks on your chats. Two minutes without an answer is no, ten for an agent's, and the first answer counts; the sandbox's settings and the agent's spec change the wait (Tools and Asking).
lnk sandbox asks # what is waiting
lnk sandbox answer k7m2pq yes # allow that call, once
lnk sandbox answer k7m2pq noasks lists each question in a table of its ID, the QUESTION and the
time it has LEFT, after which it counts as no.
With no one to ask
With neither, such as an agent in the background on a box, a tool's call
is refused at once, naming the lnk sandbox tool add <tool> --allow <call> that lets it through, and with no desktop a page to open is
refused at once, there being no browser to open it in.
Check it, and watch it
Try the sandbox from inside, see every call on its wire, and what each sandbox sent.
Check the sandbox
check plants bait, such as secrets in your home folder, in Link's
settings and in each --hide folder, and a server on another port. It
tries to reach each from inside, then removes it, and reports each try.
lnk sandbox check # the bare sandbox
lnk sandbox check --write . --internet-host '*' # as a program would run
lnk sandbox check --spec app.toml # as a spec would run, an unlisted program too
lnk agent harness check --harness link # the sandbox of your agent, as Link Harness has itWhat it reports
blocked when the sandbox stopped it, allowed when a folder or
permission you gave lets it through, failed when it was allowed but
didn't work here, missed when it should have been allowed and wasn't,
and open for a known gap.
leaked
Something nothing allows got through. It exits 1, and please report it (Security).
See every call on the wire
Each line is a call on a sandbox's proxy: when (UTC), which sandbox, the verb, where to, and what happened. The log never holds a request's path, headers or body.
lnk sandbox log # the latest 40
lnk sandbox log --lines 200 --sandbox main-link
lnk sandbox log --refused # only what was refused
lnk sandbox log --json # one JSON object per lineA sandbox's name and a verb
A sandbox is named <agent>-<harness>, a box user's name or
run-<pid>. The verb says what kind of call it was, such as connect
for HTTPS, tcp for another port or model for a hosted model, and
Security lists them all.
What happened
allowed, then ended with the bytes each way, or refused, or
failed when it was allowed but nothing answered; an upstream socket
refused for being another user's says so after failed.
See what each sandbox sent
This is what each running sandbox's proxy has carried since it started,
up from the sandbox and down to it. lnk measure reads it as an agent's
network; a hosted model's tokens are counted by its route, read from the
usage each answer gives as it passes, and lnk measure reads them as
the agent's.
lnk sandbox traffic # each running proxy: bytes up and down
lnk sandbox traffic --jsonStop or pause a sandbox
Closing a wire refuses every new call and ends open ones within a
second. stop works however an agent behaves, and the log stays.
lnk sandbox stop # close every wire and stop every agent here
lnk sandbox stop --off # open the wires again, but agents stay stopped until lnk agent start
lnk sandbox pause main-link # close the wire of one sandbox, while its program keeps running
lnk sandbox resume main-link
lnk sandbox paused # which wires are closed, and whyWithout a wire
A sandbox without a wire, such as an agent with --network-mode host,
stops only when its program does. An agent with no sandbox keeps its
wire, but it closes only the calls the agent sends its proxy, which no
wall keeps it to.
A wire that pauses itself
A proxy also pauses its own wire when its calls look like no normal work, and notifies you. That means 30 calls refused within a minute, 20 different targets refused within 10 minutes, or any call to a cloud's metadata service.
Seeing it
lnk sandbox paused and lnk sandbox log show which wires are paused
and why. lnk agent status shows its own, for a box where no
notification shows.
Let someone SSH into a sandbox
On a box, a person gets a Linux user of their own, whose every SSH
session is in their sandbox: A box's
users.
What their key runs is lnk sandbox enter, which any key's forced
command can run.
restrict,pty,command="/usr/local/lib/lnk/lnk-sandbox sandbox enter --spec /etc/lnk/users/alice/alice.toml --folder /home/alice" ssh-ed25519 AAAA...A session
A shell, a command, scp or sftp (the session's
SSH_ORIGINAL_COMMAND) all run in the sandbox the spec makes, named for
its file, with the folder the one place it writes. Its [commands] must
let /bin/bash run, which a session is.
--check
lnk sandbox enter --check says what the sandbox opens, a line each,
and runs nothing; a command after -- runs in place of the session's.
Make the sandbox work on this machine
On Ubuntu 23.10 and newer, ready also offers to add an AppArmor profile
with sudo, or prints the two commands. lnk agent start, run and
check run ready first, once a boot on Linux, and on a Mac there's
nothing to do.
# Linux
sudo apt install bubblewrap
lnk sandbox readyWhere things live
Link keeps the sandbox's files in your settings folder, where no
sandbox reaches them: ~/.lnk/sandbox/ holds your tools, the wire's log
and waiting questions, and ~/.lnk/specs/sandbox.toml lists the specs
run here, so a new one asks first
(how).
More about it
What the sandbox guarantees, and its known gaps, are in Security. Why it works this way is in Decisions. How a plugin uses it is in Plugin Contracts. What to do when it fails is on Troubleshooting.
Docs
- Features: Every feature of the sandbox, one row each, grouped by what it opens or closes
- Choose What It Can Reach: The programs a sandboxed program runs, the hosts, machines and models it reaches, the tools it calls and the pages it opens, each a flag of
lnk sandbox runand a key of a spec (Sandbox) - Tools and Asking: The tools that run outside every sandbox, and how the sandbox asks you before one's call or a page goes through (Security)
- Configuration: The files
lnk sandboxkeeps, and what each one holds - Security: What every sandbox guarantees, what can cross it, and how a spec is checked
- Gaps and Limits: What the sandbox leaves open, what
checkreports asopen, and where it can't run (Security) - Decisions: Why the sandbox works the way it does
- Troubleshooting: What to do when the sandbox can't start here, a program in it can't write, run or reach what it needs, or your agent's grants don't hold (Sandbox, Permissions)