Back to blog
·by Patrick Hofmann

It's Not the Process That Separates Agents — It's Their Key

If one process holds all agents, how do you keep one's shell command from reading another's secrets? The answer wasn't to pull the secrets back into the process. A note on a decision: isolation belongs where the tool runs — and the agent's key is the real boundary.

OpenApeAI AgentsSecurityInfrastructureBuilding in Public

The moment one process holds all agents, an uncomfortable question arrives. If agent A runs a shell command — what stops it from reading agent B's secrets? Both now run in the same process, and that one runs with full rights.

The obvious answer is wrong, and seeing that was the whole point.

The obvious, wrong answer

The instinct: the central process holds each agent's secrets in memory and passes them to the right agent on a tool call. Then A has its own, B has its own, and nobody reaches the other's.

Two things argue against it. First, the central process would then have to hold every agent's plaintext secrets in memory. That turns the one process into a worthwhile target — crack it, and you have everything. Second, the passing-through path doesn't work as simply as it sounds: when you drop to the agent's user, the environment gets stripped along the way anyway. Handing the secrets over that channel fails on the mechanics itself.

So: don't pass through.

The decision

Isolation moves to the place where a tool actually runs. Only tools with side effects — shell, file, spawn — drop down; read-only tools like an HTTP GET don't need it. When such a tool runs, the call drops to the agent's OS user, and in that dropped context the agent unseals its own secrets itself.

The crucial word is "itself." The agent owns its own key — it lives in its home, readable only by its user. Its secrets lie encrypted next to it, sealed to its key. No one else can open them, not even the central process that triggered the tool call. The plaintext comes into being only in the dropped context, at the moment of execution, and only there.

The central process thereby holds not a single plaintext secret and no environment maps of the agents. Crack it, and there's nothing to decrypt. Only the agent has the key, in its home.

What this turns around

Before, I thought the OS user isolates because it carries a process. In fact it's the other way around. The user isolates through file permissions — it can't read another user's home, the kernel sees to that. The process was never necessary. It was just the place the tooling happened to run.

With that, an old cost falls away too. Previously every agent materialized its own environment at creation — tooling that got set up whether it was needed or not. Now what a tool needs comes into being only when the tool runs. "Eager at spawn" becomes "lazy on demand." The one costs at every agent, the other only at actual work.

The boundary, in the end, isn't the process and not even the user on its own. It's the key. Whoever has it gets to the secrets — and exactly one agent has it, in exactly one home.

Where this stands

This decision is made and confirmed in a first attempt: in one process two agents, each drops to its user, each correctly unseals its own secrets, and the cross-access to the other's home fails with "Permission denied." That's the property that matters, and it holds.

What's still outstanding is the rebuild that wires this mechanism into the live tool path — today the sessions in the new model still run without tools. I write that down because it honestly belongs here: the direction stands and is checked, the wiring is still in progress. VERIFY: confirm tool-drop implementation status before publishing

One spot stays delicate and deserves naming. The whole guarantee hangs on classifying each tool correctly — does it have a side effect and must drop, or is it read-only and may run up top? A misclassified tool that runs up top with full rights breaks the separation. That classification is a security boundary and has to be tested as one, adversarially, not in passing.

Closing

The easy answer would have been to pull the secrets back into the process and pass them through. It would have made the one process a vault and failed on the mechanics. The better answer doesn't move the secrets but the place of separation: down to the moment a tool runs, and with it to the only thing that truly separates — the key only the agent holds.