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 tokenThen, 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
How to Debug an AI Agent That Called the Wrong API
Working backwards from the response your agent got to the tool-selection decision that caused it, which is where most of the real debugging time goes.
iPaaS Was Built for Integrations, Not Agents
Deterministic trigger-action versus non-deterministic tool choice, and why the governance model that works for one doesn't transfer cleanly to the other.
Build Your Own MCP Server or Buy an Execution Layer
The real cost line isn't the connectors. It's the maintenance of the stitching layer underneath them, and that bill doesn't stop arriving after launch.
