The most common mistake in 2026 AI agent deployments is exposing secrets via env vars or config files. That's what docs show and ships fastest. It's also what turns a compromised agent into immediate credential exfiltration.
Right 2026 posture: runtime injection via broker, never long-lived storage in the agent's environment.
The problem
An agent that can execute code (and most 2026 agents can, directly or via tools) reaches os.environ, ~/.config, the filesystem. If you've stored:
OPENAI_API_KEY=sk-xxxAWS_ACCESS_KEY_ID=AKIA...DATABASE_URL=postgres://user:pass@...GITHUB_TOKEN=ghp_...
…a compromise reads everything in one command, often exfiltrated before you notice.
The broker pattern
1. The broker
A separate service holding secrets behind an authenticated API: Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, Doppler, 1Password Connect, Infisical. Single source of truth for plaintext secrets.
2. Agent identity
The agent proves identity via:
- Federated OIDC: runtime (Kubernetes, Lambda, ECS) proves identity through a cluster-signed token. No long-lived credentials.
- Or short-lived tokens rotated every 15-60 minutes.
3. Just-in-time request
`` agent → broker (OIDC identity + scope) → broker checks authorization + policy → returns ephemeral token (15 min, scoped) → agent calls tool → token expires ``
Secret never persistent in agent memory. If compromised, attacker gets at worst an ephemeral, scoped, 15-minute token.
Variants
Minimal start
If Vault isn't on the table:
- Secrets encrypted server-side.
- Fetched at agent init via authenticated call.
- Held only in memory (no
os.environ, no file). - Agent can't execute arbitrary user code in the same process.
Not perfect. Better than env vars.
Advanced: secrets never in agent memory
For high-impact actions (payment, signature):
- Agent never receives the secret.
- Agent calls an internal endpoint that "performs a payment".
- Endpoint has secret access via broker and applies its own policy.
Agent works blind on credentials. Gets a business primitive, not a technical one.
Local dev
A .env in the project is the reflex. Better:
direnv+ 1Password CLI: fetched on shell entry, wiped on exit.- Dev-dedicated tokens, sandbox-scoped, force-rotated weekly.
- No production access from dev accounts — staging only.
What looks safer than it is
At-rest encryption alone
Encrypted on disk, decrypted in memory at startup. Memory dump exposes everything. At-rest encryption defends against disk theft, not application compromise.
Filesystem permissions
chmod 600 on .env — but the agent runs under the same user. And most agents get compromised via code they execute themselves.
Log scrubbing
Good practice. But if the attacker has executed code, they read secrets directly, not from logs.
The simple test
Three questions before go-live:
- Memory dump mid-session: how many long-lived secrets do you find?
- Attacker runs arbitrary code for 60 seconds: which high-impact actions?
- How many humans have seen your production secrets plaintext?
Target: 0, none, ideally no humans. Gaps are documented technical debt.