Least Privilege for AI Agents:Scoped Tokens
Most AI agent risk comes down to one thing: the agent can do more than the task requires. If a token can reach every API for hours, a single manipulated instruction can cause real damage. Least privilege flips that. You hand the agent the smallest possible key, so a mistake or an attack stays small. This is the prevention side of agent security, and it pairs with the response side in how to instantly revoke an AI agent's access.
What Does Least Privilege Mean for an AI Agent?
It means the agent's credential should answer four questions as narrowly as possible: how long is it valid, which service can it call, what is it allowed to do, and does it still count as fresh. OWASP calls the failure to do this Excessive Agency, listed as LLM06. The fix is not one setting, it is a set of small limits that add up. See our guide on excessive agency in AI agents for the wider idea.
| Limit | What it controls | OwlTokenGuard setting |
|---|---|---|
| Short life | How long a token stays valid | expiresInSeconds |
| Narrow audience | Which service the token is for | audience |
| Single purpose | What the token may be used for | purpose on verify |
| Freshness | Whether a recent re-check is required | reauthAt and getMinimumReauthAt |
How Do You Give an Agent a Short-Lived, Scoped Token?
Start by setting a short life and a clear audience when you create the token manager. Install the library first:
npm install @restingowlorg/owltokenguard
import { createTokenManager } from "@restingowlorg/owltokenguard";
// One manager per service the agent may call, each with its own audience
const billingScope = createTokenManager({
algorithm: "HS256",
hmacSecret: process.env.JWT_SECRET,
audience: "billing-api", // this token is ONLY for the billing service
expiresInSeconds: 120, // valid for two minutes only
onSessionTerminate: async () => {},
});
const issued = await billingScope.generateAccessToken({
sub: "agent-42",
role: "read-invoices", // your app reads this to allow only reads
});
A token scoped to billing-api for two minutes cannot be replayed against your user service, and it stops working almost immediately. If the agent needs another service, issue a second, separate token for that service rather than one broad token for everything.
How Do You Enforce the Scope When the Agent Calls a Tool?
Scoping only helps if you check it. When you verify the token, require the exact purpose and audience. A token meant for one service will be rejected everywhere else.
const auth = await billingScope.verify(token, {
purpose: "access",
audience: "billing-api", // must match, or verification fails
});
// Then apply your own rule from the claims
if (auth.payload.role !== "read-invoices") {
throw new Error("this token may only read invoices");
}
How Do You Require Freshness Before Sensitive Actions?
Some actions are risky enough that you want proof the session is still trusted, not one that started hours ago. OwlTokenGuard supports a freshness check: you stamp when the agent last re-authenticated, and you can require any token older than a cutoff to be refused. This is useful after a security event, or before a high value action such as a payment.
const minimumReauthAtBySub = new Map();
const manager = createTokenManager({
algorithm: "HS256",
hmacSecret: process.env.JWT_SECRET,
expiresInSeconds: 120,
getMinimumReauthAt: async (sub) => minimumReauthAtBySub.get(sub),
onSessionTerminate: async () => {},
});
// Force a fresh check for this agent from now on
minimumReauthAtBySub.set("agent-42", Math.floor(Date.now() / 1000));
Least Privilege Checklist for AI Agents
- 1Give each token the shortest life the task allows, measured in minutes, not hours.
- 2Set a specific audience so a token works with only one service.
- 3Issue a separate token per service or tool, never one broad token for everything.
- 4Verify the purpose and audience on every call, and reject anything that does not match.
- 5Put a role or scope in the claims and enforce it in your own code.
- 6Require freshness before sensitive actions such as payments or account changes.
- 7Keep a fast way to revoke, so scoping and cancelling work together.
npm install @restingowlorg/owltokenguard and scope your agent tokens as above. Then add the response side from how to revoke an AI agent's access, and read excessive agency and insecure output handling for the bigger picture.