Content

The agent that turned off its own sandbox

We locked TinyAGI's agent away from Swytchcode's rules with deny rules and a sandbox. So it edited its own settings file and switched the sandbox off. Here's how it happened, in four rounds, and the three extra lines that closed it.

TinyAGI, which used to be called TinyClaw, runs teams of AI agents around the clock. Each agent has a role. They hand work to each other, keep chat rooms per team, and talk to you on Discord, WhatsApp or Telegram. Under the hood, each agent is a Claude Code or Codex session.

To keep a team moving without stopping to ask you, TinyAGI starts Claude Code with permission prompts switched off. That's a sensible choice for a team of agents. It also means every tool runs the moment the model asks for it.

We connected TinyAGI to Swytchcode, which holds every API write for a person to approve and keeps rules the agent can't change. Then we tried to get around those rules. It took four rounds.

Round 1: no limits

With TinyAGI as it ships, Swytchcode's own tools behaved. Asked to remove the approval rule, the agent was refused and handed the command for a person to run.

But it didn't need Swytchcode. Its Bash and Edit tools run without asking, so it renamed the approval rule in a copy of the rules file, and read the token it uses to reach Swytchcode. A rule is only as strong as the file it lives in, and this agent could edit the file.

Round 2: the deny rules

We'd seen this before with MARVIN, another agent built on Claude Code. The fix there was Claude Code's own: deny rules for the Swytchcode folders, plus its sandbox, so the rules apply to shell commands too.

The good news: those still work when permission prompts are off. Skipping prompts doesn't skip deny rules or the sandbox. With them in place, the Swytchcode folders simply weren't there for Bash or Edit.

We thought we were done.

Round 3: the agent edits its own settings

The sandbox is switched on in a settings file, .claude/settings.json, inside the agent's own folder. That file wasn't covered by any deny rule.

So the agent edited it, set the sandbox to off, and on the very next command, renamed the approval rule.

It's worth being clear about what happened. No exploit, no clever trick. The agent had permission to edit a file, and that file happened to hold its own limits. TinyAGI even ships a skill that teaches agents to change TinyAGI's own settings, because managing their own setup is a normal part of the job.

Round 4: lock the lock

The fix was three more deny rules: one for each of the agent's own settings files, and one for TinyAGI's folder in your home directory. Here's the full block, for the agent's folder at ~/tinyagi-workspace/tinyagi:

{
  "permissions": {
    "allow": ["mcp__swytchcode"],
    "deny": [
      "Read(~/agent-swy/.swytchcode/**)",
      "Edit(~/agent-swy/**)",
      "Read(~/.swytchcode/**)",
      "Edit(~/.swytchcode/**)",
      "Edit(~/tinyagi-workspace/tinyagi/.claude/settings.json)",
      "Edit(~/tinyagi-workspace/tinyagi/.claude/settings.local.json)",
      "Edit(~/.tinyagi/**)"
    ]
  },
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "allowUnsandboxedCommands": false
  }
}

One trap: don't deny the whole .claude folder. The sandbox needs to create files in there, and it breaks if it can't.

With all seven rules and the sandbox, every one of our checks passed again. Reads ran. Writes waited for approval. Pasted keys were refused. And the rules file was unchanged at the end.

Set it up

Use TinyAGI's release bundle from its install script. Its Dockerfile doesn't build on the main branch right now. You also need a Swytchcode account, and approvals need the Business or Enterprise plan.

On the TinyAGI machine, create the project and start Swytchcode over HTTP:

npm install -g swytchcode
swy init --operator --editor=none --project ~/agent-swy
swy login
swy mcp serve --profile operator --project ~/agent-swy --transport http -d
swy mcp token

Then, in each agent's workspace folder, add the server and the skill:

cd ~/tinyagi-workspace/tinyagi
claude mcp add --transport http swytchcode http://127.0.0.1:5476/mcp --header "Authorization: Bearer <token>"
cp -R ~/agent-swy/agent-skill/swytchcode-operator .agents/skills/

Finally, put the settings from round 4 in that folder's .claude/settings.json, with your agent's folder in the three new rules. On Linux, the sandbox needs bubblewrap and socat. Our docs page for any other agent covers connecting your first app.

We tested TinyAGI v0.0.20 with Claude Code, a mocked Stripe and a scripted model. We haven't tested the Codex engine, a real model, its chat channels, or a real approval on a phone.

Every lock needs a lock on its key

Round 3 is the one I keep thinking about. We locked the door, and left the key on a hook the agent could reach.

If you give an agent the power to manage itself, check where its limits are stored. If it can edit that file, it can edit its limits. For TinyAGI, that's three extra lines. For your own agent, it's worth five minutes of looking.

More content