Skip to content
Go back

Your Agent Doesn't Need the Secret. It Needs the Result.

Colosseum, Rome
Colosseum, Rome

TL;DR


If you’ve wired vault-backed credentials into an agent setup, you’ve made a call that feels obviously correct: stop putting API keys in .env files and shell profiles, store them in a vault, pull them at runtime. op read, op run, scoped service account tokens — the mechanics are solved and well-documented.

Here’s the question that call doesn’t answer: what happens in the half-second after the agent reads that secret into its own process?

The pattern — vault → op read → environment variable → agent subprocess — is a real improvement over plaintext files checked into a repo. The fourth post in this series covered exactly this shape: an M2M secret resolved into memory just long enough to acquire a token, then discarded. That resolution window is still a window. The secret ends up inside the agent’s memory, in its environment, reachable by anything the agent can be talked into doing. A prompt injection that gets an agent to print $API_KEY or send it to an attacker-controlled endpoint doesn’t care that the key came from a vault five minutes earlier, or that it was only there for milliseconds. It cares that the key is sitting in os.environ right now.

This isn’t hypothetical. SANS frames it precisely: an agent holding valid credentials with a manipulable prompt is a confused deputy — an entity with the right to act, tricked into acting on someone else’s behalf. The vault did its job. The leak happens one layer up, in the part of the system the vault was never built to protect.

What’s converging to close the gap

Three patterns are showing up across security research and tooling released this year, and they share one property: each one reduces what the agent can hold — not where the secret is stored.

Scope the vault to the task, not to the person. One vault holding everything an agent might ever touch is one stolen token away from everything. The fix mirrors what cloud teams already do with IAM roles: a deploy role that can deploy and nothing else, a read role that can read and nothing else. Apply the same split here — a narrow vault per trust boundary, a separate scoped token per vault, read-only by default. Compromise one, and an attacker gets one bounded set of secrets, not the keys to everything you own.

Make the token’s lifetime match the task’s lifetime, not the session’s. Several 2026 writeups land on the same arithmetic: a two-minute agent run backed by a sixty-minute token has an exposure window thirty times longer than the work that justified it. NIST’s NCCoE published a concept paper in February naming SPIFFE/SPIRE, OAuth 2.0, and zero-trust identity as the standards under consideration specifically for agent identity — all three assume a credential should expire with the task it was issued for, not the human’s coffee break.

Stop handing the secret to the agent at all. This is the one that changes the architecture, not just the timer. Agent Vault, an open-source project from Infisical, puts a proxy between the agent and the internet. The agent’s outbound traffic routes through it; the proxy terminates the connection, recognizes the destination host, injects the matching credential, and forwards the request. The agent receives the API response. It never receives the API key. Route every outbound call through a broker that authenticates on the agent’s behalf, and a prompt injection that convinces the agent to dump its credentials finds nothing to dump — there’s nothing there to find.

What’s missing from the current default

The pattern most builders land on still resolves the secret into the agent’s own runtime. op read puts the value in a variable. op run puts it in the environment. Both are real improvements over a plaintext file in a repo. Neither removes the secret from the blast radius of a single bad tool call.

That’s not an argument against vault-backed credentials. It’s the floor, not the ceiling — and it’s an argument for asking the next question: of the credentials your agent currently holds, how many does it actually need to hold, versus simply needing the result of using one?

An agent that calls a payment API doesn’t need the API key. It needs “charge succeeded” or “charge failed.” An agent that queries a database doesn’t need the connection string. It needs the rows back. In both cases the credential is a means to an end the agent doesn’t care about — and every means it’s carrying is something it can be talked into handing over.

So what

The question worth sitting with isn’t “where do my secrets live.” Vaults answer that one well. The question is: does my agent, at any point in its execution, possess a value that — if pulled out through one manipulated tool call — would matter?

If the answer is yes, the fix isn’t a better vault. It’s removing the agent from the chain of custody — narrower scopes so a leak is bounded, shorter-lived tokens so a leak expires fast, and brokered access so there’s nothing to leak in the first place. The agent gets the outcome it asked for. It never gets the thing that produced it.


This is the eighth post in a series on 1Password as infrastructure. It extends the fourth, which treated a secret resolved into agent memory as the trust boundary, and the seventh, which scoped that resolution to a narrower vault and token. This post argues both are still the floor: the fix that removes the exposure window entirely is brokering, not scoping. Start from the first post.


Share this post on:


Previous Post
One Token for Everything Is Still One Token
Next Post
Builder's Daily Is a Fleet, Not a Newsletter