{"slug": "your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call", "title": "Your AI agent runs with all your permissions. I built a cage for each tool call, in Rust", "summary": "A developer released CleiMesh, an MIT/Apache-2.0 Rust node that enforces per-tool-call permissions for AI agents, issuing capability tokens that can only shrink as they are delegated and requiring a signed receipt before any action runs. The system combines path-scoped filesystem access, taint tracking that blocks clean-only tools like writes and sends once an agent has read untrusted content, and a draft agent-action-receipts format that logs digests and pseudonyms rather than data. The developer tested it against OpenClaw running a local Qwen3 4B on Ollama with a mail carrying a hidden instruction, and cautions that CleiMesh only contains traffic that passes through it and does not solve prompt injection.", "body_md": "A subagent got a simple task: read a project's docs and say how to run it. It read `docs/readme.txt`, found \"make run\", and then asked for one more file: `~/.ssh/id_rsa`.\n\nWhy it asked doesn't matter. A hidden instruction in something it read, a buggy third-party tool, a model that \"thought\" the key would help. What matters is what happens next, and in most setups today the file is read. Not because anyone granted the subagent access to the key, but because nobody granted anything to anyone: the tool runs as your user, and your user can read your key.\n\nThere's an old name for this: **ambient authority**. The kernel doesn't know about agents. It sees user `ana` and processes of `ana`. It can't ask \"was this Ana, Ana's agent, or the tool her agent's subagent downloaded yesterday?\".\n\nI wanted something one level down: per tool call, decided by a permission that can only shrink as it is handed on, and proved afterwards.\n\n[CleiMesh](https://github.com/cleitonaugusto/cleimesh) is a Rust node (MIT or Apache-2.0) that puts five pieces together:\n\n`./project/docs` can't physically open `./project`.` draft-sahu-agent-action-receipts` format. Digests and pseudonyms, never the data. No receipt, no run.`--taints` (mail, web) returns content to an agent, tools marked `--clean-only` (write, send) are refused for that agent's whole chain until a human clears it. Handing the work to a fresh subagent doesn't launder it.\n\n```\n# Reading the inbox brings in outside content; writing to the outbox acts on the world\ncleimesh token issue <agent> --tool file_read --read ~/inbox --taints -o read.json\ncleimesh token issue <agent> --tool file_write --write ~/outbox --clean-only -o write.json\n```\n\nI ran OpenClaw with a local Qwen3 4B on Ollama and a mail carrying a hidden instruction to write a secret to a file.\n\nThat first act is the honest limit: CleiMesh only contains what goes through it. `cleimesh doctor` reads Claude Code's and OpenClaw's config and warns when the agent still has its own file or shell tools. And it doesn't \"solve\" prompt injection: the model can still be fooled, and an allowed action can still be the wrong one. What the node adds is a rule outside the model that the model can't argue with.\n\n```\ncurl -fsSL https://github.com/cleitonaugusto/cleimesh/releases/latest/download/install.sh | sh\n# or from source:\ncargo build -p cleimesh-cli\nCLEIMESH=target/debug/cleimesh examples/demo/demo.sh\n```\n\nThe demo runs in a fresh `/tmp` directory with a fake project, a fake `~/.ssh` and throwaway keys. It's alpha: the threat model in the repo lists what it protects, what it doesn't, and the gaps before 1.0.\n\nRepo: [https://github.com/cleitonaugusto/cleimesh](https://github.com/cleitonaugusto/cleimesh)\n\nI'd like opinions on two things: grouping receipt fsyncs without weakening \"no receipt, no run\", and the guest ABI (core module now, Component Model before 1.0).\n\n*I also wrote up the design, the attacks and the mistakes in a book, [AI Agents in a Cage](https://leanpub.com/ai-agents-in-a-cage).*", "url": "https://wpnews.pro/news/your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call", "canonical_source": "https://dev.to/cleiton_augusto_/your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call-in-rust-430c", "published_at": "2026-10-21 20:33:47+00:00", "updated_at": "2026-10-21 20:41:07.554642+00:00", "lang": "en", "topics": ["ai-agents", "ai-safety", "ai-tools", "developer-tools"], "entities": ["CleiMesh", "OpenClaw", "Qwen3", "Ollama", "Rust", "Claude Code"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call", "markdown": "https://wpnews.pro/news/your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call.md", "text": "https://wpnews.pro/news/your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call.txt", "jsonld": "https://wpnews.pro/news/your-ai-agent-runs-with-all-your-permissions-i-built-a-cage-for-each-tool-call.jsonld"}}