{"id":22906,"date":"2026-07-27T15:30:27","date_gmt":"2026-07-27T15:30:27","guid":{"rendered":"https:\/\/scannn.com\/from-zero-trust-to-zero-custody\/"},"modified":"2026-07-27T15:30:27","modified_gmt":"2026-07-27T15:30:27","slug":"from-zero-trust-to-zero-custody","status":"publish","type":"post","link":"https:\/\/scannn.com\/lv\/from-zero-trust-to-zero-custody\/","title":{"rendered":"From Zero Trust to Zero Custody"},"content":{"rendered":"\n<div dir=\"auto\">\n<p><em>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.<\/em><\/p>\n<p><audio data-testid=\"audio-element\" src=\"https:\/\/2amsecurity.substack.com\/api\/v1\/audio\/upload\/b24575ac-3b37-47c9-a038-179e9c2890b2\/src\" preload=\"none\">Audio playback is not supported on your browser. Please upgrade.<\/audio><\/p>\n<div class=\"captioned-image-container\">\n<figure><a target=\"_blank\" href=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!vQUI!,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d78c331-7fe9-4e6d-8fd6-74d276142337_1408x768.png\" data-component-name=\"Image2ToDOM\" class=\"image-link image2 is-viewable-img can-restack\"><\/p>\n<div class=\"image2-inset\"><picture><source type=\"image\/webp\" srcset=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!vQUI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d78c331-7fe9-4e6d-8fd6-74d276142337_1408x768.png 424w, https:\/\/substackcdn.com\/image\/fetch\/$s_!vQUI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d78c331-7fe9-4e6d-8fd6-74d276142337_1408x768.png 848w, https:\/\/substackcdn.com\/image\/fetch\/$s_!vQUI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d78c331-7fe9-4e6d-8fd6-74d276142337_1408x768.png 1272w, https:\/\/substackcdn.com\/image\/fetch\/$s_!vQUI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d78c331-7fe9-4e6d-8fd6-74d276142337_1408x768.png 1456w\" sizes=\"100vw\"\/><\/picture><\/div>\n<p><\/a><figcaption class=\"image-caption\"\/><\/figure>\n<\/div>\n<p>Zero Trust won by killing an assumption.<\/p>\n<p>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 \u2014 cloud, mobile, SaaS, remote work \u2014 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.<\/p>\n<p>It worked. It is, correctly, the default posture of every serious security program now.<\/p>\n<p><span>But every framework carries an assumption it never states out loud, and Zero Trust has one. It is buried in the word <\/span><em>verify<\/em><span>. Zero Trust tells you to authenticate the actor and authorize the request. What it quietly assumes is that <\/span><em>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.<\/em><span> 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.<\/span><\/p>\n<p>Then we started building principals that can be talked into things.<\/p>\n<p><span>I have written before about the <\/span><a href=\"https:\/\/srajangupta.substack.com\/p\/the-trust-inversion-from-browser\">Trust Inversion<\/a><span> \u2014 <\/span><\/p>\n<div data-component-name=\"DigestPostEmbed\" class=\"digestPostEmbed-flwiST\"><a href=\"https:\/\/srajangupta.substack.com\/p\/the-trust-inversion-from-browser\" rel=\"noopener\" target=\"_blank\"><\/p>\n<div class=\"pencraft pc-display-flex pc-gap-16 pc-reset\">\n<div style=\"width:70px;height:70px;\" class=\"pencraft pc-reset\"><picture><source type=\"image\/webp\" srcset=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!1ZxO!,w_140,h_140,c_fill,f_webp,q_auto:good,fl_progressive:steep,g_auto\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cd45bfd-a011-4bbf-8719-c849de738420_1408x768.png\"\/><img decoding=\"async\" src=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!1ZxO!,w_140,h_140,c_fill,f_auto,q_auto:good,fl_progressive:steep,g_auto\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cd45bfd-a011-4bbf-8719-c849de738420_1408x768.png\" sizes=\"100vw\" alt=\"The Trust Inversion: From Browser as OS to AI IDE as OS\" width=\"140\" height=\"140\" class=\"img-OACg1c smSquare-NGbPBa pencraft pc-reset\"\/><\/picture><\/div>\n<div class=\"pencraft pc-display-flex pc-flexDirection-column pc-reset\">\n<h4 class=\"pencraft pc-reset color-pub-primary-text-NyXPlw line-height-24-jnGwiv font-display-nhmvtD size-20-P_cSRT weight-bold-DmI9lw reset-IxiVJZ\">The Trust Inversion: From Browser as OS to AI IDE as OS<\/h4>\n<\/div>\n<\/div>\n<p><\/a><\/div>\n<p><span>that the interesting attacks on AI agents are not attacks <\/span><em>against<\/em><span> the agent but attacks <\/span><em>through<\/em><span> it, using its legitimate, verified access as the execution mechanism. The agent does not need to be hacked. It needs to be <\/span><em>misdirected<\/em><span>. Zero Custody is what happens when you take that seriously and follow it all the way down.<\/span><\/p>\n<p><span>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 \u2014 any of these can redirect what the agent does next. You can verify the agent\u2019s 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 <\/span><em>behavior<\/em><span> of the correctly-identified thing.<\/span><\/p>\n<p><span>This breaks Zero Trust\u2019s buried assumption cleanly in half. Verification answers <\/span><em>who is this actor<\/em><span>. It says nothing about <\/span><em>what this actor will be convinced to do with what it is holding.<\/em><span> 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.<\/span><\/p>\n<p>So verification is no longer the frontier. Verification is table stakes. The frontier is custody.<\/p>\n<p><span>Here is the principle, stated as plainly as I can: <\/span><strong>the reasoning loop should hold nothing that matters.<\/strong><\/p>\n<p><span>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\u2019s 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 <\/span><em>implicit<\/em><span> trust from the network. Zero Custody removes <\/span><em>durable<\/em><span> trust from the actor \u2014 and then makes sure that when the trust turns out to be misplaced, which it periodically will, the agent\u2019s hands are empty.<\/span><\/p>\n<p><span>The word to sit with is <\/span><em>custody<\/em><span>. Not access \u2014 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 \u2014 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.<\/span><\/p>\n<p>Start with the obvious one, because it is the cleanest.<\/p>\n<p><span>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 <\/span><em>not<\/em><span> to do this \u2014 tokenization took the card number out of the merchant\u2019s hands, the service mesh took auth out of the app, workload identity killed the static key file \u2014 and then, in the rush to make agents useful, we handed all of it back.<\/span><\/p>\n<p>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.<\/p>\n<pre><code><code># what actually lives in the agent's environment\nOPENAI_API_KEY=gw_virtual_9f2c...   # only works through the gateway\nGITHUB_TOKEN=__brokered__           # a placeholder, not a credential\nHTTPS_PROXY=http:\/\/gateway:8080     # the only way out<\/code><\/code><\/pre>\n<p>The tempting fix is to store the secret more carefully \u2014 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\u2019s 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.<\/p>\n<p>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.<\/p>\n<p>This is the one people miss, and it is where Zero Custody stops being a fancy name for a credential broker.<\/p>\n<p><span>Credentials are not the only thing worth stealing. The context window fills up with the <\/span><em>actual sensitive material<\/em><span> of the work \u2014 customer records, PII, PHI, transaction details, internal financials \u2014 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.<\/span><\/p>\n<p><span>So apply the same move to data. The agent does not need to <\/span><em>hold<\/em><span> the raw sensitive values; it needs to reason over their <\/span><em>shape<\/em><span>. 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.<\/span><\/p>\n<pre><code><code>inbound to the agent:   customer = \"J*** D**\", ssn = &lt;tok:9x2f&gt;, balance = &lt;band:high&gt;\nagent reasons, produces: \"flag &lt;tok:9x2f&gt; for manual review\"\noutbound at the gateway: &lt;tok:9x2f&gt; re-identified only for the authorized downstream system<\/code><\/code><\/pre>\n<p><span>The agent does genuinely useful work \u2014 flags the account, drafts the response, routes the ticket \u2014 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, <\/span><em>even though we trust the agent to do the task.<\/em><span> 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.<\/span><\/p>\n<p>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:<\/p>\n<div class=\"captioned-image-container\">\n<figure><a target=\"_blank\" href=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png\" data-component-name=\"Image2ToDOM\" class=\"image-link image2 is-viewable-img can-restack\"><\/p>\n<div class=\"image2-inset\"><picture><source type=\"image\/webp\" srcset=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 424w, https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 848w, https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 1272w, https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 1456w\" sizes=\"100vw\"\/><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png\" width=\"1456\" height=\"604\" data-attrs=\"{&quot;src&quot;:&quot;https:\/\/substack-post-media.s3.amazonaws.com\/public\/images\/ff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:604,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:120886,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image\/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https:\/\/srajangupta.substack.com\/i\/208620221?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}\" alt=\"\" srcset=\"https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 424w, https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 848w, https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 1272w, https:\/\/substackcdn.com\/image\/fetch\/$s_!53ts!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep\/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff29fbb6-7a7d-4fcb-a926-d1f34d194e91_1548x642.png 1456w\" sizes=\"auto, 100vw\" loading=\"lazy\" class=\"sizing-normal\"\/><\/picture><\/div>\n<p><\/a><\/figure>\n<\/div>\n<p><span>Every row is the same instinct as the credential broker, pointed at a different asset. Take it out of the loop\u2019s hands. Hold it somewhere the loop cannot argue with. I break each of these into a concrete control plane in the next piece \u2014 the six pillars of a secure agent harness \u2014 but the organizing idea is entirely this one: <\/span><em>hold nothing that matters.<\/em><\/p>\n<p>I should be clear about what Zero Custody is not.<\/p>\n<p><span>It is not a replacement for Zero Trust. It is what Zero Trust <\/span><em>becomes<\/em><span> 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.<\/span><\/p>\n<p><span>And it is not free, in a way I have to name. Taking custody away from the agent does not delete the custody \u2014 it <\/span><em>concentrates<\/em><span> 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.<\/span><\/p>\n<p>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 \u2014 even an actor you have every reason to trust \u2014 is not a place to store your secrets or your data.<\/p>\n<p><span>Zero Trust asked <\/span><em>who are you.<\/em><span> Zero Custody asks <\/span><em>why are you holding that.<\/em><span> Verify everything. Then make sure the thing you just verified is holding nothing worth taking.<\/span><\/p>\n<p data-attrs=\"{&quot;url&quot;:&quot;https:\/\/srajangupta.substack.com\/p\/where-is-my-agentlock-file?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&amp;token=eyJ1c2VyX2lkIjoxNTYwNzE1NDQsInBvc3RfaWQiOjE5NDE2NjUxMSwiaWF0IjoxNzc5NzQ2MzY1LCJleHAiOjE3ODIzMzgzNjUsImlzcyI6InB1Yi0yMDU2Nzk4Iiwic3ViIjoicG9zdC1yZWFjdGlvbiJ9.SF8_A7KWma8qKM7GWbydqfpQoY7twNFS67vV96ZgR_c&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}\" data-component-name=\"ButtonCreateButton\" class=\"button-wrapper\"><a href=\"https:\/\/srajangupta.substack.com\/p\/where-is-my-agentlock-file?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&amp;token=eyJ1c2VyX2lkIjoxNTYwNzE1NDQsInBvc3RfaWQiOjE5NDE2NjUxMSwiaWF0IjoxNzc5NzQ2MzY1LCJleHAiOjE3ODIzMzgzNjUsImlzcyI6InB1Yi0yMDU2Nzk4Iiwic3ViIjoicG9zdC1yZWFjdGlvbiJ9.SF8_A7KWma8qKM7GWbydqfpQoY7twNFS67vV96ZgR_c\" class=\"button primary button-wrapper\"><span>Share<\/span><\/a><\/p>\n<p data-attrs=\"{&quot;url&quot;:&quot;https:\/\/srajangupta.substack.com\/p\/where-is-my-agentlock-file\/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}\" data-component-name=\"ButtonCreateButton\" class=\"button-wrapper\"><a href=\"https:\/\/srajangupta.substack.com\/p\/where-is-my-agentlock-file\/comments\" class=\"button primary button-wrapper\"><span>Leave a comment<\/span><\/a><\/p>\n<\/div>\n<p><a href=\"https:\/\/2amsecurity.substack.com\/p\/from-zero-trust-to-zero-custody?utm_source=tldrit\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. Audio playback is not supported on your browser. Please upgrade. Zero Trust won by killing an assumption. For twenty years, security was built on location. Inside the [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":22907,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[143],"tags":[],"class_list":["post-22906","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai"],"_links":{"self":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/22906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/comments?post=22906"}],"version-history":[{"count":0,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/22906\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media\/22907"}],"wp:attachment":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media?parent=22906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/categories?post=22906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/tags?post=22906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}