Let it make a mess.

Review the work, not every keystroke.

dejima runs Claude Code or Cline in a firewalled container with your project inside. The agent works without permission prompts and reaches only what you've approved. When the session ends, the container is removed, and your project is what's left.

Free and open source under the GPL. Runs on Linux.

Your machineInside dejima

~/my-project $ dejima
>The import job broke after the deploy. Find out why and fix it.
works for a while, with no permission prompts
●pypi.org isn't reachable from the sandbox. Can you run dejima-allow pypi.org?
>You should now have access to pypi.
●Thanks. Tests pass. Opened a pull request: "Fix the import job".
>/exit
Session over. The container, and everything the agent did in it, is gone.
kept~/my-project, and a pull request to review

Your machine

~/my-project $ dejima-allow pypi.org

Your machineInside dejima

~/my-project $ dejima
>The failing job's log is in ~/shared. Find out what broke.
works for a while
●Found it: the importer parses dates in the server's timezone. The fix is committed, and the write-up is in ~/shared/report.md.

Your machine

~/my-project $ dejima-share path
/home/user/shared/projects/-home-user-my-project
~/my-project $ cp ~/Downloads/import-error.log "$(dejima-share path)"
~/my-project $ ls "$(dejima-share path)"
import-error.log  report.md
same~/shared inside the sandbox is this folder on your machine
The agent stays inside. You approve from your machine.

Reviewing every action doesn't work

Everything an agent hands back should be reviewed before you use it. Approving each step on the way there is a different job, and it doesn't work.

  • It doesn't scale. A session is hundreds of tool calls, and reading them all isn't realistic.
  • A prompt shows you the command, not what it does. npm test runs whatever the agent wrote ten minutes ago, and the prompt looks the same either way.
  • Approved calls still do the damage. Hiding something in a call you approve is easy, and most of the mess comes from calls nobody would think to refuse.

So dejima makes the question irrelevant. Let the agent wreck its own environment and shout into the void. Nobody hears it unless you let them, and everything it breaks is gone when the session ends. What's left to review is the work, once, at the end.

Mess, mistakes, malice. None of it matters.

Three things agents do, most likely first. Mess is the agent working. Mistakes are the agent working badly. Malice is the agent working against you. dejima doesn't try to prevent any of them.

  1. Let it make a mess.

    Agents install packages, write scratch files, start servers and leave them running, and clone repositories to read an error. On your machine, nothing cleans that up for you. Over weeks, the mess and the changes to your environment build up until the machine is no longer the one you set up, and eventually no longer works. In dejima it lives in a container that's removed when the session ends. Your project and the folders you chose to share are what stays.

  2. Let it break things.

    A wrong rm, an "I'll just reset this config", a global install that breaks your toolchain. An agent running as you can do that to anything you can touch. In dejima it's wrecking an environment that was going to be deleted anyway. Your project is the exception, so keep it in version control. Pushes anywhere but the remote you allowed are refused, and so is merging.

  3. Let it work against you.

    It reads untrusted text all day: pages it finds while researching, the docs of every package it touches, the output of every command it runs. Any of it can carry instructions, and you never see most of it. The code it installs runs whatever its authors wrote, and nothing guarantees a model wasn't trained to act against you. On your machine all of that runs as you, beside ~/.ssh and your cloud credentials. In dejima there's no SSH key to read, your model login is a placeholder by default, and nothing connects unless you approved it.

You don't sandbox an agent because you know it's hostile. You sandbox it because you can't know it isn't.

What about auto mode?

An auto mode hands the approvals to a second model, so you stop being asked. It's still per-action review, just automated.

  • The mess still happens. Routine actions go straight through, on your machine.
  • A model checks a model. The reviewer is the same kind of model, reading the same text that fooled the agent. When it's wrong, nothing is underneath.
  • It feels safe. Click Allow without reading and at least you know you're cutting a corner. Here one agent approves what another can do, and it looks like oversight.
  • You pay for the reviewer. Every reviewed action is another model call, all session long.

Auto mode asks a model whether an action is safe. dejima makes the question irrelevant.

What about the harness's own sandbox?

Some harnesses can sandbox the commands they run. It's a boundary the harness draws around itself.

  • The harness isn't inside it. It covers the commands the harness starts. The harness's own edits, hooks, and connection to the model aren't among them, so a hijacked agent doesn't have to escape anything.
  • Its rules are a file the agent can write. The policy lives in your home directory, and the agent runs as you.
  • Its reach is your account. The harness runs beside your SSH keys, dotfiles, and other projects.
  • Nothing outside it is watching. The only record of what happened is written by the process under suspicion.
  • It feels safe. "It has a sandbox" sounds like the problem is solved, so the agent runs on your machine with nothing else around it.

A harness's sandbox is enforced by the thing it bounds. dejima is enforced from outside it.

Type dejima where you used to type claude or cline

You need Docker with Compose, jq, python3, and Claude Code or Cline installed and signed in on your machine. No dedicated machine or other services needed.

git clone https://github.com/dejima-org/dejima
cd dejima && ./install.sh
cd ~/my-project && dejima

install.sh puts dejima in ~/.local/bin and writes a starter config that picks Claude Code. For Cline, change harness = claude-code to harness = cline in ~/.config/dejima/config.

  • Your setup comes with you. Your CLAUDE.md, settings, skills, hooks, plugins, and git identity carry over.
  • Your login stays on your machine. The container gets a placeholder, and a proxy on the host adds the real credential to each request.
  • Nothing is pushed by default. The agent commits locally. Pull requests are a config change when you want them.
  • Alongside, not instead. Installing dejima doesn't change how claude behaves when you run it directly.

Supported on Linux. macOS is untested: nothing known rules it out, and reports are welcome. Only the tip of main is supported, so pull to update; dejima tells you when your checkout is behind.

Not a locked box

A sandbox you keep leaving isn't containing anything. If it's something you'd do with an agent, there's a way to do it in dejima, and you're the one who opens it.

More than a dozen projects, months of use, and not once have I started an agent directly on my machine.

dejima's author
What dejima offers for each need
If you needdejima has
A site the firewall blocksdejima-allow, for this session, this project, or every project, even mid-session
A service on your own networkInternal domains, named explicitly
A package or toolchaindejima-dep: apt, pip, cargo, npm, or a tarball
Files from elsewhere on diskExtra mounts, read-only or read-write
A browser for testing a frontendPlaywright and Chromium, already installed
To pass a file in or out~/shared, one per project
To hand work from one agent to anotherThe same ~/shared: every session on a project sees one folder, at the same path
An editor instead of the agent--cmd nvim, or anything else, in the same box
A different modelAnthropic, OpenRouter, or a model you host yourself
An agent with none of your filesdejima --isolated

The agent knows these exist. It's told it's in a sandbox, so a blocked domain becomes a one-line request to you instead of a failed task or a workaround.

What you can't do

  • Run Docker or other containers inside a session.
  • Run GUI apps, or open a session's dev server in your own browser. The agent drives a headless browser and hands you screenshots.
  • Install system packages mid-session. Declare them and they're there next launch.
  • Use a debugger like gdb or strace, mount filesystems, or ping.
  • Use IPv6, a GPU, or other hardware.
  • Run on anything but Linux, officially.

The full list, with workarounds

What the agent can't do

  • Grant itself anything. Domains, dependencies, and approvals are decided on your machine, out of its reach.
  • Merge, or push anywhere but the remote you allowed.
  • See your other projects, or their agent memory and transcripts.
  • Keep anything you didn't give it a place for.

Or hand it less

Two modes for a session that should see less of your machine, or reach less of the network. They combine.

Isolated: nothing before it, nothing after it

dejima --isolated

No project is mounted, no memory or transcript crosses in or out, none of your approvals apply, and there's no forge credential. A fresh ~/shared is the one thing that outlives it. For a one-off task that doesn't belong to a project.

Sealed: no DNS, only IP addresses you name

dejima --require-sealed

No domain is permitted and DNS lookups go nowhere, so the only thing the session can reach on the network is an IP address you named. Point that at a model you serve yourself, and nothing from the session goes anywhere else. It refuses to start unless it really sealed, and says what kept it open. It needs a harness with no model API of its own: Cline can seal, Claude Code can't. With no registry to install from, approve dependencies ahead of time.

Together, dejima --isolated --require-sealed starts with nothing of your machine or history, with no DNS and network access only to the IP address you named. Isolated isn't a stronger sandbox on its own. The firewall and credential boundary are the same for every session; it changes how much of your machine is inside them.

Around the work

All of these are off until you turn them on.

Pushing workflows
It pushes a branch and opens a pull request on GitHub, Gitea, or Forgejo, then stops. Merging is yours. Give it its own forge account and its permissions are smaller than yours.
Remote access
Check on a running session from a browser or your phone, and get a notification when it needs you.
Change audits
An audit reports changes to anything that could run code later, like git hooks and agent config. The summaries it writes as it compacts are kept on your machine.
Project-level grants
It lists its domains and tools in .dejima/. Listing grants nothing: you approve on your machine, and the session can't approve itself.
Request and conversation logging
Every DNS lookup and blocked connection, and the conversation if you opt in, sent to your own Loki. Nothing goes anywhere otherwise.

Start with one layer. Add more as the risk grows.

A container bounds what an agent touches directly. What it can affect goes further: its pull requests run on your CI, and an escape would land on your machine and your network. dejima has a layer for each, and none of them counts on the others holding.

  • dejima, on your laptop or a devbox

    Contains the agent. Everything else here is optional.

  • dejima-ci-hardener

    When the agent's pull requests run on CI you host. A pull request runs on your runner before anyone reads it. Hosted CI is the other answer.

  • dejima-devbox-hardener

    When dejima moves to a dedicated VM on a network you care about. If something escapes the container, a firewall enforced outside the VM limits what it reaches.

  • dejima-guard

    On top of dejima-devbox-hardener, when sessions run unattended for long stretches. A second machine notices when the devbox changes, and tells you.

darner: send a task, get the work back

darner runs each task in a fresh, isolated dejima session and brings the work back. Send it from a browser or a Matrix room, answer what it asks while it works, and get a summary and a zip of what it made.

A task is what you want done, in plain words. How it runs is a saved config: which agent and model, what it knows going in, what it can reach, and which tools and files it gets. You write the config once and reuse it, so a request only has to say what you want.

A saved config
# configs/recipes
ctx: myapp
harness: cline
backend: self-hosted
model: qwen3-14b
internal: recipes.example.com:8443
file: recipes-token
A request, sent from your phone
@dragonlet the import job started failing
after the deploy, find out why
config: recipes
allow: pypi.org

The request is the task plus one exception. The config is everything else.

  • Built to keep dejima's boundary. The agent is presumed hostile, and so is what it writes. darner's key on the dejima host runs only the launcher, output is read as plain files into a zip darner builds, and agent text arrives inert.
  • Short-lived. Nothing about a session outlives it. Its prompt, requests, and screens go when it ends, and its output once you've collected it.
  • On a leash while it works. It can ask for a domain or for help mid-task, and you answer allow or deny. It never grants itself anything.
  • Yours to share, carefully. A task can use any agent and model your dejima host has, on your accounts. Share an instance the way you'd share your Claude login or API key.

darner on GitHub

Early, and honest about it

Nothing here has been through an outside review or audit. dejima is a real improvement over running an agent directly on your machine, not a guarantee against a determined attacker. It plans for a container escape rather than assuming there won't be one: with dejima-devbox-hardener, an escape lands in a VM, behind a firewall enforced outside it. dejima has one maintainer, and no support is promised. SECURITY.md says what is claimed and where to report a vulnerability.