DEV Community

Stop Giving AI Agents Standing API Keys

Least Privilege, but for Non-Human Identities

We have decades of practice applying least privilege to people. Agents are different in three ways that make standing credentials especially risky:

  • They act fast and unattended. A misused human credential might do damage for minutes before someone notices. An agent loop can make thousands of calls before anyone looks.
  • Their instructions are attacker-reachable. Prompt injection means the thing deciding how to use a credential can be steered by untrusted input.
  • They fan out. One agent calls another, which calls a tool, which calls an API. Scope has to travel with the request, not live in a shared secret.

So the unit of access for an agent should be a short-lived, narrowly scoped credential minted for a specific task - not a copy of your production key.

What "Scoped" Actually Means

A useful scoped credential pins down several dimensions at once:

  • Audience - which upstream API or MCP server it is valid for.
  • Operations - which methods or tools, e.g. read but not write.
  • Resources - which endpoints, paths, or object IDs.
  • Lifetime - minutes, not months. It expires on its own.
  • Rate - a ceiling on calls per window, so a runaway loop is contained.

In practice a grant looks something like this:

{
  "audience": "api.github.com",
  "operations": ["GET"],
  "resources": ["/repos/acme/billing/issues/*"],
  "expires_in": "15m",
  "rate_limit": "60/min"
}

When all five are tight, a leaked credential is worth very little: it stops working almost immediately and only ever opened a small door.

The Broker Pattern

The cleanest way to deliver this is a credential broker that sits between your agents and your secrets. The model never sees a real secret. Instead:

  • The agent asks the broker to perform an operation (often via an MCP tool).
  • The broker checks policy: is this principal allowed to do this, right now, within limits?
  • If allowed, the broker injects the real credential at the edge, makes the call, and returns the result.
  • Every step is recorded.

Because the secret is resolved at call time and never handed to the model, you can rotate or revoke it without touching a single agent. And because the broker is the one place every agent call flows through, it is also the natural place to enforce scope and capture an audit trail.

A Practical Migration Path

  • Inventory the keys your agents hold today. Anything long-lived and broad is the priority.
  • Move secrets behind the broker. Replace in-agent keys with a reference the broker resolves.
  • Tighten scope per task. Start permissive, then ratchet down using what the audit log shows the agent actually needs.
  • Shorten lifetimes. Once issuance is automatic, expiry becomes free.

The end state: agents carry no durable secrets, every credential is minted for a purpose and expires on its own, and you can answer "what could this agent do?" by reading a policy instead of guessing. Least privilege was always the goal - scoped, short-lived credentials are how agents get it by default.

Comments

No comments yet. Start the discussion.