← All posts

Why AI agents need more than API keys

For twenty years, the API key has been the workhorse of machine-to-machine access. You provision one, drop it in an environment variable, and a service uses it to call another service. It works because the two sides are stable: the caller does a known set of things, the key rarely changes, and a human is usually nearby when something breaks.

AI agents break every one of those assumptions.

A key says who, not what or when

An API key answers exactly one question: is this caller who they claim to be? It says nothing about what the caller is allowed to do right now, against which resource, on whose behalf. For a payroll service calling a tax API, that is fine — the set of actions is fixed and reviewed.

An agent is different. It decides its next action at runtime, from context you did not write by hand. The same agent that summarized a document a second ago might now try to email it, delete it, or wire money. A credential that only proves identity has no opinion about any of that. By the time you notice, the action has already happened.

Agents act at machine speed, and so do their mistakes

A human misusing a credential is bounded by how fast a human can click. An agent runs a loop. It can take hundreds of actions a minute, chain tool calls together, and amplify a single bad instruction — a prompt injection, a hallucinated parameter, a misread goal — into a cascade before anyone looks at a dashboard.

Static keys have no concept of "stop." Rotating one is a deploy. Revoking access usually means waiting for a token to expire or scrambling to invalidate it everywhere it was copied. That is the wrong response time for something that can do real damage in seconds.

Agents delegate, and delegation needs scope

Modern agent systems are not one agent. A planner hands work to a researcher, which hands a narrower task to a tool-runner. Each hop should narrow what is possible, not copy a full-power credential down the chain. An API key has no notion of "you may pass on a subset of what you hold, for five minutes, revocably." So in practice teams either over-share one powerful key or build bespoke plumbing for every handoff.

What runtime authorization looks like instead

The fix is to stop asking who are you once at the door and start asking should this specific action happen every time. That means:

  • Check before execute. Every consequential action is evaluated in the moment — agent, action, resource, and context — and returns an allow, deny, or "needs approval," not just a 200.
  • Short-lived, opaque tokens. Credentials that carry no standing power on their own and can be revoked instantly, so "stop" is a single call, not a redeploy.
  • One model across surfaces. Whether the agent acts through an MCP tool, an agent-to-agent call, or a direct API, the same authorization decision applies — not three different security stories.
  • Scoped, revocable delegation. Each handoff narrows permissions to a subset of the parent, with its own lifetime, independently revocable.
  • An audit trail of decisions. Not just "a request happened," but what was asked, what was decided, and why.

In practice the integration is small. You wrap the agent's actions with a check and let the platform make the call:

from agenttrustid import AgentTrustClient

client = AgentTrustClient(
    base_url="https://your-agenttrust-endpoint.example",
    api_key="sk_live_...",
)

# Ask before the agent acts — not just whether the caller is authenticated,
# but whether THIS action should happen right now.
decision = client.actions.check(
    agent_id="agent-123",
    tool_name="email.send",
    session_id="session-abc",
)

if not decision.allowed:
    raise PermissionError(decision.reason)

send_email(...)  # only runs if the action was authorized

The agent keeps its autonomy. What changes is that every action it takes passes through a decision you control, recorded for later, and reversible the instant something looks wrong.

API keys answer a question agents stopped asking. The real question — should this happen, right now, on whose behalf? — is one you can only answer at runtime. That is the problem AgentTrust ID is built to solve.