Secrets managers vs credential brokers for AI agents: Doppler, Vault, Infisical, and where each fits

Doppler, HashiCorp Vault, and Infisical solve storage, rotation, and access control for AI agents, but they still deliver the raw key into the agent process. Here is where each secrets manager stops, where a credential broker starts, and why you want both.

May 28, 202614 min read

Secrets managers vs credential brokers for AI agents: Doppler, Vault, Infisical, and where each fits.

You did the responsible thing. You stopped pasting API keys into .env files committed to git. You moved everything into Doppler, or HashiCorp Vault, or Infisical. Secrets are encrypted at rest, access is scoped to service tokens, rotation is automated, and there is an audit trail. You feel good about it.

Then you wire up an AI agent. A LangChain app, a Cursor MCP setup, a Claude Code-style harness. And the moment that agent process starts, OPENAI_API_KEY and STRIPE_SECRET_KEY and GITHUB_TOKEN are sitting right there in os.environ, in plaintext, readable by anything running in that process. Your secrets manager fetched them and handed them over, exactly as designed.

That is the gap. A secrets manager answers "where is the secret stored and who can fetch it." It does not answer "what happens once the agent is holding it." For a deterministic web service that distinction barely matters. For an LLM agent that can be steered by untrusted input, it matters a lot, because a prompt-injected agent can read its own environment, log it, or exfiltrate it through a tool call.

This post is an honest comparison. It is not "throw away your secrets manager." Doppler, Vault, and Infisical are good at what they do, and you should keep using one. The point is to be precise about where each one stops, where a different category of tool (a credential broker) begins, and why the two compose rather than compete.

The thing all three have in common at runtime

Before the comparison, the shared fact that the rest of the post hangs on: at execution time, every mainstream secrets manager delivers the raw credential into the agent process. They differ enormously in storage, governance, and how short-lived the credential is. They do not differ on this one point.

Here is where the secret actually lands in the two most common agent frameworks.

LangChain's documented setup pattern puts the key straight into the process environment, then the model client reads it from there:

python
import os, getpass
if not os.environ.get("OPENAI_API_KEY"):
    os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API key: ")

from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")   # reads the key from os.environ

LlamaIndex is identical in spirit. The raw key has to be in the process before you initialize the LLM:

python
import os
os.environ["OPENAI_API_KEY"] = "sk-..."          # raw key, in-process

from llama_index.llms.openai import OpenAI
from llama_index.core import Settings
Settings.llm = OpenAI(model="gpt-4o-mini")

It does not matter whether the value came from a hardcoded string, a .env file, Doppler, or Vault. By the time the model client can use it, the plaintext key is in the running Python process. We covered why that single fact is the root problem in stop putting API keys in environment variables, and why a prompt-injected agent turns it into an exfiltration path in how prompt injection becomes credential exfiltration. Keep both in mind, because every tool below either lands the secret in that environment or deliberately avoids doing so.

Doppler: excellent storage, env-var delivery

Doppler is a clean, fast secrets manager with a great developer experience. Its core agent story is the CLI:

bash
doppler run -- python my_agent.py

doppler run fetches the latest versions of your secrets and injects them as environment variables into the running process. Your agent then reads them with os.getenv("OPENAI_API_KEY"). For non-interactive or CI agents you swap interactive auth for a scoped, read-only service token:

bash
export DOPPLER_TOKEN="dp.st.prd.xxxxx"   # scoped to one project + config
doppler run -- python my_agent.py

This is genuinely good. Service tokens scope a runtime down to a single project and config, secrets never touch your repo, and rotation is centralized. If you are not using something like this yet, do.

But notice what doppler run does: it puts the plaintext secret into the child process environment. Doppler's own documentation treats env-var injection as a trade-off and points to a file-based alternative for tighter threat models. When the vendor itself frames env-var delivery as a trade-off, you should take it seriously. There is no separate "Doppler agent broker" product that moves the secret off the process. Doppler's agent story is doppler run plus scoped service tokens, and that story ends with the raw key in os.environ.

Where Doppler stops: storage, versioning, scoped service tokens, rotation, audit. Where it does not go: keeping the secret out of the agent's reach at execution time.

HashiCorp Vault: short-lived credentials, and a newer agent story still maturing

Vault is the heavyweight. Its defining strength for agents is dynamic, short-lived credentials. Instead of a static, permanent key, an agent tool call can request a just-in-time credential that is scoped and expires on a short TTL:

bash
vault read database/creds/agent-role     # returns a TTL-bound username/password
# or
vault kv get -field=api_key secret/agents/billing-agent

This is a real reduction in blast radius. A leaked dynamic credential is worth far less than a leaked permanent key, because it is narrowly scoped and dies on a timer. Vault has also been moving toward stronger identity for non-human actors, which is the right direction for the non-human identity problem where NHIs vastly outnumber human users.

HashiCorp has signaled native AI agent support for Vault, broadly along three lines:

  • Agent identity: register and manage agent activity separately from human and traditional non-human identities.
  • Identity-based policy: per-request access decided by the intersection of a human policy, an agent baseline, and an agent ceiling.
  • Ephemeral, per-request authorization: scoped authorization bound to the token lifecycle.

Two honest caveats. First, treat the native-agent features as still maturing rather than something you can architect around as if it shipped and stabilized today; check HashiCorp's own release notes for the current availability of any specific capability. Second, and more important for this comparison: even Vault's core model still hands the credential to the agent to use. Dynamic credentials shrink the TTL and the scope dramatically. They do not remove the secret from the agent process. Vault reduces the value of a leak. It does not eliminate the surface that leaks.

What Vault does brilliantly is the identity, policy, and short-lived-issuance side of the problem. It does not claim to inject at the network boundary, so do not assume it keeps the credential out of the agent's hands.

Where Vault stops: identity, policy, dynamic short-lived credentials, governance at enterprise scale. Where it does not go: keeping the credential out of the agent process at the moment of use.

Infisical: the most honest case study in this whole post

Infisical is interesting because the same company makes both a classic secrets manager and a credential broker. That single fact does more to validate this comparison than anything I could argue.

The classic Infisical Agent is a daemon. It authenticates, fetches secrets, renders them through Go text/template, and writes the result to a file path your app reads:

bash
infisical run -- python my_agent.py      # injects as env vars
yaml
# agent-config.yaml
templates:
  - source-path: secrets.tpl
    destination-path: /run/secrets/.env
code
# secrets.tpl
{{- with secret "OPENAI_API_KEY" }}OPENAI_API_KEY={{ .Value }}{{- end }}

This is the file-delivery pattern Doppler's docs offer as an alternative to raw env vars. It is better than env vars in some threat models because the secret is on disk rather than in the environment block. But the agent still reads the raw value out of that file (or, with infisical run, out of os.environ). The plaintext key still ends up where the agent can touch it.

Infisical also ships Agent Vault: a separate, open-source HTTP credential proxy, written mostly in Go, that sits between your agents and the APIs they call. You configure the agent with a dummy placeholder instead of the real key. Agent Vault listens on a proxy port (14322), intercepts each outbound request, and attaches the real credential before forwarding it on:

bash
# the agent is configured with a placeholder, not the real key:
export ANTHROPIC_API_KEY="__anthropic_api_key__"
# outbound traffic is routed through the broker on :14322, which swaps the
# placeholder for the real credential before forwarding to the API.

(Agent Vault is open source under a custom license; check the repo's LICENSE file for the exact terms.) Infisical's own framing is the cleanest statement of the principle: agents should not possess credentials, because a compromised agent then has no surface to reason about, probe, or attempt to circumvent. It targets agent harnesses such as Claude Code and custom setups.

Sit with that. A leading secrets-manager vendor publicly conceded that storage is not the same as agent-boundary protection, and built a broker to close the gap. That is the whole thesis of this post, conceded by someone with no incentive to invent the category. It also means a credential broker is not some single-vendor novelty. It is a recognized pattern with multiple implementations, which is exactly what you want before you trust an architecture.

Two different jobs, named plainly

Here is the distinction the whole comparison turns on:

  • A secrets manager answers: where is the secret stored, who or what is allowed to fetch it, how often does it rotate, and is there an audit trail. Doppler, Vault, and classic Infisical all do this well.
  • A credential broker answers: how do I let the agent make an authenticated request without the agent ever holding the credential. It injects the real secret at the network boundary, as the request leaves, so the agent's environment holds only a placeholder.

They are not substitutes. A broker does not store, version, or govern your full secret inventory across teams and environments. A secrets manager does not keep the key out of the agent process at execution time. Put bluntly: the secrets manager is upstream (storage, rotation, governance), the broker is at the runtime edge (the agent boundary). For more on this category specifically, see agent credential brokers in 2026 and the wider top agent proxy tools survey.

A side-by-side, honest about where each one stops:

CapabilityDopplerHashiCorp VaultInfisical (classic)Credential broker
Encrypted storage of full secret inventoryYesYesYesNo (not its job)
Centralized rotation / versioningYesYesYesPer-token refresh only
Scoped access tokens / policyService tokensStrong (identity + policy)YesGlobal allow/deny per run
Short-lived dynamic credentialsLimitedYes (core strength)LimitedDepends
Identity for non-human / agent actorsPartialYes (identity + agent features maturing)PartialAt the request boundary
Keeps the raw key OUT of the agent processNo (env vars)No (delivered to agent)No (file or env vars)Yes (placeholder + boundary injection)

That last row is the one a secrets manager cannot fill, by design. It is not a knock on Doppler or Vault. It is just a different job.

Cursor MCP: where this bites in practice

If you use Cursor, you have already met this gap. MCP servers take their secrets in the env block of mcp.json, at .cursor/mcp.json per project or ~/.cursor/mcp.json globally:

json
{
  "mcpServers": {
    "stripe": {
      "command": "npx",
      "args": ["-y", "@stripe/mcp"],
      "env": { "STRIPE_SECRET_KEY": "${env:STRIPE_SECRET_KEY}" }
    }
  }
}

Cursor's docs say they support ${env:NAME} interpolation and advise using environment variables for secrets rather than hardcoding them. Good advice. The catch: some users have reported that interpolation in mcp.json did not actually resolve from their shell, leaving them no option but to paste the literal sk_live_... into the file. So the official story is "interpolation works," and the real-world story for some setups is "you end up with a plaintext key on disk that the agent can read." If you hit that, do not assume it is your mistake. It is a known rough edge. We go deeper on MCP plumbing in what is MCP, a developer primer and on hardening it in the self-hosted MCP server auth checklist.

This is the exact spot where a broker earns its keep. You can paste the key into mcp.json and hope interpolation behaves, or you can route the server's outbound traffic through a broker so the config holds only a placeholder and the real key never lands on disk where the agent runs.

Where a broker fits, and where one open-source option lands

Concretely, the broker pattern looks like this. Authsome is an open-source, local-first, MIT-licensed credential broker for agents. You authorize a provider once, then launch the agent under a local proxy:

bash
uv tool install authsome
authsome login github          # browser PKCE, or device code over SSH/CI
authsome run -- python my_agent.py

Inside that agent, the environment variable for the provider holds only a placeholder like OPENAI_API_KEY=authsome-proxy-managed. The local HTTPS proxy matches the outbound destination and swaps in the real Authorization header as the request leaves. The agent never reads or holds the real key, so a prompt-injected agent has nothing in its environment to leak. The vault is encrypted SQLite under ~/.authsome/, with no cloud, no account, and an append-only JSONL audit log of every credential read and refresh. For headless and CI agents the device-code login is covered in headless agent OAuth, the device code flow explained, and a full Claude Code wiring example lives in wiring Claude Code to GitHub, Linear, and Stripe.

Two honest notes so this stays a comparison and not a pitch. First, Authsome is not the only broker. Infisical's Agent Vault is the other obvious one, and the fact that the pattern has multiple implementations is a point in its favor, not a turf war. Second, a broker is not a secrets manager. There is a global allow/deny proxy mode per run, but there is no per-agent policy engine deciding which agent may use which provider. If you need cross-team inventory, environment promotion, and rich policy, that is what your Doppler or Vault is for.

How to actually decide

Tip

The decision is rarely "which one." It is usually "which secrets manager, plus do I add a broker for the agent boundary."

  • Pick the secrets manager that fits your org. Doppler for clean DX and fast setup. Vault if you need dynamic short-lived credentials, strong identity, and enterprise policy, keeping in mind that its native-agent features are still maturing. Infisical if you want open source with a solid agent daemon. Any of them solves storage, rotation, and access control well.
  • Add a broker when the agent process is the threat surface. That means anything LLM-driven and exposed to untrusted input: web-browsing agents, MCP servers, autonomous task runners. The broker is what keeps the raw key out of reach when the agent itself might be turned against you. See running AI agents in production with credentials for the production framing.
  • Compose them. Store and rotate in the manager, feed the broker from the manager, and let the broker handle the runtime edge. The manager governs the secret's lifecycle. The broker governs whether the agent ever touches it.
Warning

Do not read this as "brokers replace secrets managers." They do not, and no credible broker claims to. A broker stores almost nothing and governs almost nothing. It does exactly one thing the managers cannot: keep the credential off the agent. Use both.

The honest summary fits in a sentence. Doppler, Vault, and Infisical are the right answer to "where do my secrets live and who can fetch them." None of them is the answer to "how does my agent authenticate without ever holding the key." For that last question, the answer is a credential broker, and the strongest evidence it is the right answer is that a secrets-manager vendor built one too.

Priyansh Khodiyar

Priyansh Khodiyar

Maintainer

Works on authsome and the agentr.dev tooling.