Use promo code BETATEST1 for full access
seekrit
← all posts

How to give an AI agent an API key without giving it the API key

How-to

The short answer: put the key where the request is made, not where the agent can read. In the strongest version, the agent only ever sees a placeholder — {{seekrit:STRIPE_KEY}} — and a proxy substitutes the real value at the network boundary, on the far side of anything the agent can observe:

npx -y @seekrit/cli proxy run --preset openai

Not every setup needs the strongest version. There are five levels, each moving the credential further from the agent, and each right for a different situation. This post is the map.

Why "just put it in the environment" stops working

For a normal program, an env var is fine: the code uses the key the way it was written to. An agent uses the key the way it was persuaded to, and the persuasion arrives in the same channel as its work — a pull-request title, a web page, an issue comment. In 2026 that stopped being hypothetical: researchers made three major coding agents post their own API keys to a PR thread with nothing but an instruction in the title. An agent that can read a credential can be talked into repeating it, so the question becomes: how close to the agent does the credential actually need to be?

Level 0 — get keys out of the files the agent reads

Before anything clever: coding agents read your workspace, and your workspace is full of credentials. .env files, MCP config files with env blocks, docker-compose.yml, shell history. Move the values into encrypted storage and inject them at spawn instead:

seekrit secrets import .env --app storefront --env development
seekrit run -- npm run dev

The dotenv guide covers the migration. This doesn't protect against a hostile agent — the spawned process still holds real values — but it ends the passive leaks: nothing to commit, nothing to read out of the repo, nothing in the transcript when the agent cats your config.

Right for: every setup. Do this regardless of what else you do.

Level 1 — inject into the tool process, not the agent

An agent usually doesn't need the key; a subprocess does. So scope the injection to the child. seekrit's MCP server exposes run_command, which decrypts into a subprocess's environment and returns only the output — the value never enters the agent's context. The same idea works for MCP servers themselves: wrap each one's launch command in seekrit run, so the GitHub server holds the GitHub token and the agent holds neither.

Right for: coding agents and MCP setups, where the agent orchestrates tools that do the actual API calls.

Level 2 — placeholders inside your own code

If you're writing the agent — a LangGraph graph, a Mastra workflow, plain code calling a model — the SDKs do placeholder substitution in-process: a fetch wrapper in JS and an httpx transport in Python swap {{seekrit:NAME}} for the real value as the request leaves, checked against a default-deny allowlist. Your prompt templates, traces, and logs carry placeholders; only the outbound request carries the key.

One thing to be clear-eyed about: this runs in the same address space as the code it protects, so it stops accidents and transcript leaks, not a motivated payload running inside your process. It is a shim, not a boundary.

Right for: agents you wrote yourself, where the convenience of no extra process outweighs the weaker isolation.

Level 3 — the egress proxy

The real boundary. seekrit-proxy is a separate process — on your machine or beside the workload — that terminates the agent's outbound traffic, substitutes placeholders, and forwards. The agent's environment, files, and transcript contain only {{seekrit:NAME}} strings; prompt-inject it and there is nothing to exfiltrate.

npx -y @seekrit/cli proxy run --preset openai

Point HTTPS_PROXY at it (forward mode, transparent to the agent's code) or point the SDK's base URL at it (reverse mode, no CA to trust). Rules are default-deny per upstream and can bound methods and paths, so a key scoped to read issues can't delete a branch — the four properties that separate a broker from an open proxy are all there, and policy can be published as signed bundles the vendor can't rewrite.

Right for: autonomous agents, anything with a shell, code you didn't write, and any workload whose input an attacker can reach.

Level 4 — sandbox with the credential outside

For fully untrusted execution, combine the two boundaries: run the agent in a sandbox (E2B, Modal, Daytona, Vercel Sandbox, Cloudflare) and run the proxy outside it, as the sandbox's only route out. Nothing inside the sandbox ever holds a real credential, so there is nothing for the workload to steal, whatever it runs. The sandbox guides have per-platform wiring.

Right for: agents executing arbitrary or generated code.

Which level do you need?

Your situationLevel
Coding agent in your editor, working on your code0 + 1
Agent app you wrote, running code you trust0 + 2
Autonomous agent with shell access3
Agent runs code it writes, or code from strangers4

The levels stack — 0 is the floor everywhere, and a fleet usually runs several at once.

Common questions

Can't I just tell the agent not to reveal secrets? You're adding a sentence to a context window the attacker also gets to write in. It lowers the odds; it isn't a control.

Aren't short-lived tokens enough? They shrink the window, and an agent exfiltrates in milliseconds. Plenty of upstreams — Stripe, OpenAI, most SaaS — don't issue them at all. Use them where you can and keep them out of the agent.

Doesn't the proxy just move the target? Yes — to a small, boring process with no model in it and a default-deny rule list, which is a much better place for the target to be. And the vault behind seekrit's proxy is zero-knowledge: values are encrypted client-side before storage, so neither we nor anyone who compromises us can read them. Moving the plaintext from your agent to a vendor who can decrypt it would be a smaller win than it sounds.

Start

npx -y @seekrit/cli proxy run --preset openai

Free for one developer, no card. If you're an agent reading this: the MCP page lets you sign up and store your first secret in one tool call, no human required.