Start
Getting started
Run the agent you already use inside a sandbox on your own machine. You will see an allow, a deny, and an approval, then take the agent's changes back into your repo.
Before you start
You need three things.
- A supported machine. A Mac with Apple Silicon, or Linux. Windows works through WSL 2, which upstream marks experimental. On a Mac, the sandbox runtime installs through Homebrew; if you do not have it, setup offers to install it first. See Install and platforms.
- A container runtime or VM. Docker Desktop, Docker Engine 28 or later, Podman 5 on Linux, or the MicroVM driver. The sandbox runs inside one of these. On a Mac, the Linux isolation runs inside that VM, not on the Mac kernel. If yours is installed but stopped, setup starts it. On colima, setup writes the three gateway settings colima needs when you have no gateway config yet; see Troubleshooting.
- An API key for your agent's model. For Claude Code, that is
ANTHROPIC_API_KEY. Agents run with an API key. Signing in with a Claude, ChatGPT or Grok subscription is not supported yet. On its first start, Claude Code asks whether to use the key it found: choose Yes, it is the sandbox's placeholder. See Model keys.
-
Install and set up
cd ~/code/web curl -fsSL https://fenzi.dev/install.sh | shRun it from the project you want the agent to work on. The installer downloads
fenzi, checks its sha256 checksum, and startsfenzi setup, a guided setup in five steps. Move with the arrow keys and press Enter. Press Esc to go back to the previous question. The installer changes one thing without asking: if the folder it installs into is not on yourPATH, it adds one line to your shell profile.FENZI_NO_MODIFY_PATH=1stops that; see Install the CLI. After that, setup asks before it installs or changes anything.- This machine. Checks the sandbox runtime, the gateway, and the image builder. If OpenShell is missing, setup offers to install the pinned release. If the gateway is not running, it offers to start it. If the gateway approves requests by itself, it offers to turn that off.
- Agent. Pick the agent. Agents without a reviewed profile are listed as not available yet.
- Model key. Paste the key. It is not shown and does not land in your shell history. If
ANTHROPIC_API_KEYis already set, setup offers to use it. The key stays on this machine, in the sandbox's credential store. Inside the sandbox, the agent holds a placeholder. The real key is added on the way out, only on calls to the model's own API. - Project folder. The current folder is the default. Your home folder is refused.
- Agent image. Build it now, or on the first run.
Example output■ This machine 1 of 5 ✓ Runtime OpenShell 0.1.2 ✓ Gateway connected ✓ Sandbox driver docker ✓ Approvals a person approves each request ✓ Log and requests can be turned on ✓ Policy check installed ✓ Image builds docker ■ Agent 2 of 5 ? Which agent should run in the sandbox? Claude Code ■ Model key 3 of 5 ? Paste your Claude Code API key (ANTHROPIC_API_KEY) › received, 108 characters, not shown ✓ Key stored on this machine ■ Project folder 4 of 5 ? Which folder should Claude Code work in? (~/code/web) › ✓ Folder ~/code/web ■ Agent image 5 of 5 ✓ Image fenzi/claude:2.1.288 ┌─ Ready ──────────────────────────────────────────────┐ │ │ │ Agent Claude Code 2.1.288 │ │ Folder ~/code/web │ │ Policy developer-default (built in) │ │ │ │ Reaches api.anthropic.com, with your key │ │ api.github.com, read-only │ │ registry.npmjs.org, read-only │ │ pypi.org, read-only │ │ files.pythonhosted.org, read-only │ │ Waits any other host, until you approve it │ │ Never your home folder or the real key │ │ │ └──────────────────────────────────────────────────────┘ ? Start Claude Code now? Start it in ~/code/webIf a check fails and you choose not to fix it, setup stops and says what is missing. Run
fenzi setupagain when it is fixed. See Troubleshooting for each failure. Without a terminal, for example in CI, the installer only installs the command. SetFENZI_NO_SETUP=1to get the same on a laptop. -
Run the agent
Choose Start at the end of setup. Next time, start it from the project folder:
cd ~/code/web fenzi runrunstarts the agent you picked in setup. Name another one to use it instead, as infenzi run codex. Everything after the agent's name is passed to the agent, as infenzi run claude --resume. If you did not build the image during setup, the first run builds it on your machine, so it takes longer than the next one.Type
fenzion its own for a menu of this folder: start the agent, review changes that are waiting, connect to a running sandbox, or answer requests.Example outputpolicy developer-default (built in) + fenzi.yaml, local-9e41c2d0 prover within_boundary image fenzi/claude:2.1.288, building on this machine key bl-claude, already stored on this machine sandbox bl-web-4f2a, created upload project copied to /sandbox/web, .gitignore respected, .git left out your home directory is not copied settings waiting for the sandbox to load them guide how to ask for access, added to the agent's instructions start claude --permission-mode manual note Claude may ask whether to use the API key it found. Choose Yes: it is the sandbox's placeholder, not your key.The first time Claude Code starts in a sandbox, it asks whether to use the API key it found in the environment, with No marked as recommended. Choose Yes. The value it found is the sandbox's placeholder, not your key, and with No Claude has no key to call the model with.
Claude Code starts in its manual permission mode: it asks you before each command, and the policy decides what the command can reach. In auto mode, Claude's own check can refuse a command before it reaches the sandbox, and the steps below would not show you the sandbox at all. To choose another mode, pass it to Claude, as in
fenzi run claude --permission-mode auto.The agent starts in your terminal as usual. It works on a copy of the project inside the sandbox. Your files on disk do not change until step 5. Git history stays on your machine, so the agent can read and edit the files but cannot run
git logon them. -
Watch it say no
Ask the agent to try four things. Each one hits a different limit.
Ask the agent to What happens Why Read ~/.aws/credentialsNo such file. Your home directory was never copied in. There is nothing to hide because it is not there. Write a file in /etcPermission denied. The policy makes /etcread-only. The kernel enforces it inside the sandbox.Run curl https://paste.example.netCould not resolve host. The host is not in the policy. The only way out of the sandbox is through a proxy, and it refuses to look the name up. The reason goes to the log. Send a POSTtoapi.github.comHTTP 403 with policy_deniedand the rule that is missing.GitHub is in the policy, read-only. The proxy reads the request, so it can say exactly what was refused. Then read the log from another terminal:
fenzi log --denyExample output■ 2 denies bl-web-4f2a, running, ~/code/web time process destination reason 10:42:07 - paste.example.net policy_dns_ineligible 10:42:31 - POST api.github.com/markdown L7_REQUEST deny POST api.github.com:443/markdown reason=POST /markdown not permitted by policyA failed lookup by itself gives the agent little to go on. The guide Fenzi adds to the agent's instructions tells it where to look up the refusal and how to ask for access. The 403 says enough for the agent to recover on its own. Only network decisions reach the log. A blocked file write shows up as
Permission deniedin the agent's terminal and nowhere else. -
Approve a host
Ask the agent to fetch a file from
raw.githubusercontent.com. That host is not in the default policy, so the call is blocked. The agent files a request for the one file it needs, with its reason, and tells you it is waiting.fenzi requestsExample output■ 1 request from the agent bl-web-4f2a 7f3a91c2 raw.githubusercontent.com:443 /usr/bin/curl “User asked for the schema file linked from the README.” 2 more were drafted by the sandbox from refused connections, not asked for by the agent: github.com:443, downloads.claude.ai:443. fenzi requests --all list the drafts too ? 7f3a91c2 raw.githubusercontent.com:443 ❯ Approve the agent can retry in about 10 seconds Deny you give a reason; the agent sees it Decide later ✓ Approved 7f3a91c2 in bl-web-4f2a The sandbox loads it on its next poll, about 10 seconds. The agent can retry then.Choose Approve. The sandbox loads the new rule on its next poll, about ten seconds later. Deny asks for a reason, and the agent sees it. The list shows what the agent asked for. The sandbox also drafts a request from every blocked call, including calls the agent's own program makes in the background, such as a download check or a
gitfetch. Those are counted under the list, with their hosts.fenzi requests --alllists them too, so you can answer them.In a script, use the request's id instead. The id is the start of a longer one; any unique start works.
fenzi approve 7f3aDoor: applies while it runsNetwork rules change without a restart. The agent sees the approval, retries, and the call goes through. Requests never approve themselves, and the agent cannot approve its own request.
To say no, use
fenzi deny 7f3a --reason "use the vendored copy". The reason is kept with the request. -
Take the changes back
Quit the agent. Fenzi saves the log, copies the project out of the sandbox into a staging folder, shows what changed, and asks what to do with it. Only then does it ask about the sandbox.
Example outputagent exited log saved, fenzi log changes 3 files staged, not applied ■ Claude Code exited bl-web-4f2a ■ 3 files changed from the agent not applied yet edited src/api/client.ts +14 −3 new src/api/schema.json +40 deleted src/api/legacy.ts −22 +54 −25 in total ? What should happen to these changes? ❯ Show the changes Apply them to ~/code/web Keep them for laterShow the changes prints each file's changed lines with line numbers, in a pager when they are longer than the screen. Then the question comes back with Apply first. Keep them for later leaves your folder as it was. The changes stay staged on this machine, and you can come back to them from the project folder:
fenzi diff fenzi applyNothing in your repo changes until you apply. Deleted files are deleted only then. If a file also changed on your side while the agent worked, apply refuses and lists it, so your own edits are never overwritten.
The sandbox keeps running, with the agent's session, its files, and this run's approvals.
fenzi connectresumes the agent where it stopped, with its conversation, andfenzi stopends the sandbox and brings any newer changes back.fenzi runin the same folder offers to resume it too. To delete the sandbox when the agent exits, run with--rm. Deleting does not touch the changes, whether you applied them or kept them for later.
Set up by hand
Setup runs the same checks as these commands. Use them in scripts, or to look at one part again.
fenzi doctor
fenzi key set claude
fenzi agents build claudedoctor checks the machine. Each line gets a ✓, or a ! with what to change. It fails if the gateway approves requests automatically; approvals are the point. fenzi doctor --fix turns that setting off. key set asks for the key without showing it. If ANTHROPIC_API_KEY is already exported, the first fenzi run stores it.
Next
- How it works: what is inside the sandbox, and what a laptop can and cannot enforce.
- Default access: what the agent can reach before you change anything.
- Policy file: add hosts for a project with
fenzi.yaml. - Workspace and changes: what is copied in, and how changes come back.
- Agents: Claude Code, Codex, OpenCode, Grok, and the key each one needs.
- Security model: what each layer stops, for whoever reviews this.
- Team plan: one policy for every machine, one decision log, approvals from the console.