From Zero Trust to Zero Custody
Zero Trust taught us to verify every actor. Zero Custody asks the harder question: why is that actor holding anything worth stealing?
Disclaimer: Opinions expressed are solely my own and do not express the views or opinions of my employer or any other entities with which I am affiliated to.
Zero Trust won by killing an assumption.
For twenty years, security was built on location. Inside the firewall was trusted, outside was hostile, and the whole discipline was the art of drawing that line and defending it. Then the line dissolved — cloud, mobile, SaaS, remote work — and we admitted the thing we had been avoiding: where a request comes from tells you nothing about whether it should be honored. Zero Trust replaced the perimeter with a sentence. Never trust, always verify. Trust stopped being a property of the network and became a property of identity, re-established on every single request.
It worked. It is, correctly, the default posture of every serious security program now.
But every framework carries an assumption it never states out loud, and Zero Trust has one. It is buried in the word verify. Zero Trust tells you to authenticate the actor and authorize the request. What it quietly assumes is that once you have verified the actor, the actor can be trusted to hold and use what you granted it the way its code says it will. Verify the service, hand it a token, and the service will do service things with that token. The verification is the hard part. Custody of what follows is an afterthought, because for a normal workload, custody was never the risk.
Then we started building principals that can be talked into things.
The actor you cannot verify your way out of
I have written before about the Trust Inversion —
that the interesting attacks on AI agents are not attacks against the agent but attacks through it, using its legitimate, verified access as the execution mechanism. The agent does not need to be hacked. It needs to be misdirected. Zero Custody is what happens when you take that seriously and follow it all the way down.
An AI agent is a principal whose behavior is determined by language, and some of that language is written by your attacker. A poisoned tool description, a malicious MCP server, a document in a retrieval index that the agent was helpfully asked to summarize — any of these can redirect what the agent does next. You can verify the agent’s identity perfectly. You can issue it a short-lived, cryptographically bound token that no attacker can forge. And none of it helps, because the attack does not forge the identity. It hijacks the behavior of the correctly-identified thing.
This breaks Zero Trust’s buried assumption cleanly in half. Verification answers who is this actor. It says nothing about what this actor will be convinced to do with what it is holding. And for a reasoning loop, the second question is the only one that matters, because the answer changes with every paragraph of text that enters the context window.
So verification is no longer the frontier. Verification is table stakes. The frontier is custody.
Zero Custody
Here is the principle, stated as plainly as I can: the reasoning loop should hold nothing that matters.
Not because the agent is malicious. Because its trustworthiness is not a stable property. You do not get to decide once that an agent is trusted and move on, the way you might vet a service and let it run. An agent’s trustworthiness is re-litigated on every turn by whatever text it just read, and any turn can be the one where a hidden instruction wins. Zero Trust removed implicit trust from the network. Zero Custody removes durable trust from the actor — and then makes sure that when the trust turns out to be misplaced, which it periodically will, the agent’s hands are empty.
The word to sit with is custody. Not access — custody. Who is holding the thing. Zero Trust already scopes access. Zero Custody says scoping is not enough when the scoped actor can be commandeered: take the thing out of its hands entirely and hold it somewhere the reasoning loop cannot reach. The move underneath is older than agents — custody and capability, deliberately separated. The component that does the work should not be the component that holds what makes the work dangerous. Two examples make it concrete, and they are deliberately different in kind.
Example one: it should not hold the credential
Start with the obvious one, because it is the cleanest.
Look at where the secrets live in a typical agent deployment. The model provider key is in an environment variable. The GitHub token is in the container. The database password is right there in the connection string. We spent a decade teaching systems not to do this — tokenization took the card number out of the merchant’s hands, the service mesh took auth out of the app, workload identity killed the static key file — and then, in the rush to make agents useful, we handed all of it back.
Zero Custody says the agent never holds the secret at all. It holds a placeholder. A broker at the egress hop holds the real credential and injects it into the outbound call after a policy check.
# what actually lives in the agent's environment
OPENAI_API_KEY=gw_virtual_9f2c... # only works through the gateway
GITHUB_TOKEN=__brokered__ # a placeholder, not a credential
HTTPS_PROXY=http://gateway:8080 # the only way outThe tempting fix is to store the secret more carefully — put it in a vault, encrypt it at rest, rotate it faster. None of that solves custody. Vaulting a key the agent still reads at runtime just moves custody by one hop. The moment the agent’s process can see the plaintext, it has custody, and everything in that context window can reach it. Rotation shortens the window; it does not close the door.
Now hijack the agent all you want. Convince it to exfiltrate every secret it can see. It can see nothing. The blast radius of a compromised reasoning loop no longer includes your credentials, because the credentials were never in the loop.
Example two: it should not hold the data either
This is the one people miss, and it is where Zero Custody stops being a fancy name for a credential broker.
Credentials are not the only thing worth stealing. The context window fills up with the actual sensitive material of the work — customer records, PII, PHI, transaction details, internal financials — because that is the data the agent needs to reason over to be useful. And the context window is exfiltration surface. The same injection that would make an agent leak a key will make it leak the customer table it is holding in working memory. You closed the credential door and left the data door wide open.
So apply the same move to data. The agent does not need to hold the raw sensitive values; it needs to reason over their shape. Mask, anonymize, or tokenize at the gateway on the way in, and redact on the way out, so the real values never enter the loop.
inbound to the agent: customer = "J*** D**", ssn = <tok:9x2f>, balance = <band:high>
agent reasons, produces: "flag <tok:9x2f> for manual review"
outbound at the gateway: <tok:9x2f> re-identified only for the authorized downstream systemThe agent does genuinely useful work — flags the account, drafts the response, routes the ticket — over a view it can never turn back into a real identity. If it is hijacked mid-run, the thing it tries to leak is a token that means nothing outside the gateway. We took data custody away from the loop the same way we took the keys, even though we trust the agent to do the task. That last clause is the whole point. We are not doing this because we think the agent is compromised. We are doing it because trust in a reasoning loop is not the kind of thing you can hold on to.
It generalizes past credentials and data
Once you see the move, you see it everywhere. Credentials and data are just the two most obvious things the loop should not be holding. The full list is longer, and it is the subject of the companion to this piece:
Every row is the same instinct as the credential broker, pointed at a different asset. Take it out of the loop’s hands. Hold it somewhere the loop cannot argue with. I break each of these into a concrete control plane in the next piece — the six pillars of a secure agent harness — but the organizing idea is entirely this one: hold nothing that matters.
The Honest Position
I should be clear about what Zero Custody is not.
It is not a replacement for Zero Trust. It is what Zero Trust becomes when the principal is a reasoning loop instead of a well-behaved service. You still verify every request. You still scope every identity. Zero Custody sits on top of all of that and adds the part Zero Trust never had to worry about: assume your verified, authorized, perfectly-scoped actor will periodically be turned against you by a paragraph of text, and make sure that when it is, its hands are empty.
And it is not free, in a way I have to name. Taking custody away from the agent does not delete the custody — it concentrates it, into the broker and the gateway that now hold every secret and re-identify every token. You have not removed the thing worth stealing. You have moved it to one place, on purpose, because one hardened, monitored, independently-owned place is a target you can actually defend, and a thousand copies scattered across agent memory is not. That is a real trade, and you should make it with your eyes open. The chokepoint is also a single point of failure. Design it like one.
But it is the right trade. We spent a decade learning that trust should not come from the network. The next decade is learning that trust in the actor — even an actor you have every reason to trust — is not a place to store your secrets or your data.
Zero Trust asked who are you. Zero Custody asks why are you holding that. Verify everything. Then make sure the thing you just verified is holding nothing worth taking.




