Opinion · Identity

A scoped token is not a code of conduct.

Agent identity is everywhere right now. Give every agent its own identity, issue short-lived and task-scoped credentials, carry the human's authorization through on-behalf-of flows, and log every call against a named principal. This matters. Many deployments still run agents on shared service accounts and long-lived tokens, and that needs to stop.

After the layoff-list post, the most common reply was a version of this: give the assistant its own identity with task-scoped credentials, and it never holds the broad scope needed to assemble anything dangerous.

It does not work that way. Identity decides who may reach what. The failures that matter in agent systems happen after that decision has already said yes.

What agent identity gets right

Distinct agent identities mean each action traces to a named agent instead of disappearing into a generic service account. Ephemeral, least-privilege credentials mean an injected instruction cannot widen access or outlive the credential it runs under. And when a broker holds the secrets, injection stops being a way to steal credentials, because the agent never has any.

This targets a real, common failure. NeuralTrust calls Identity and Privilege Abuse (OWASP ASI03) "the most consistently reported failure" in enterprise agent surveys, driven by shared keys, inherited sessions and overpermissioned service accounts.

If your agents still share one master token, fix that first.

The question a token cannot answer

An identity system answers one question: may this principal perform this operation on this resource? It evaluates that one call at a time, with no concept of what the call means in context.

The OWASP Top 10 for Agentic Applications lists Agent Goal Hijack (ASI01) as a separate risk from identity abuse. In incidents like EchoLeak, "hidden prompts turned copilots into silent exfiltration engines." The copilot's identity was legitimate. Its credentials were valid. The intent belonged to the attacker.

CloudZone describes the gap well: a token with crm.write can update a single record or wipe the entire opportunity table, and a correctly issued token "cannot prove that the agent's next action reflects what the user actually wants."

The natural response is finer scopes. A 2026 arXiv paper on task-scoped authorization frames the agent as a classic confused deputy, where authority attaches to the agent rather than to each concrete operation, and is direct about the fix: "The obvious fix, finer-grained scopes (e.g., transfer_up_to_500), does not work."

Three things identity cannot see

Combinations

Go back to the four questions: the headcount plan, which roles are backfill-only, who joined recently, and next quarter's on-call rota. Each is an ordinary request against a system the person may read. Together they produce an implicit layoff list.

Now give the assistant a perfectly scoped, short-lived, task-bound credential. What does the task need? HR, finance and ops. So the token carries all three. The combination worth flagging is exactly the combination the task legitimately required. Scoped credentials bound what an agent can reach. They say nothing about what it can synthesize from what it reached.

Order

Simon Willison's lethal trifecta names the three capabilities that make an agent exploitable together: private data, untrusted content, and external communication. Identity governs the first. It is silent on the other two, and silent on sequence.

The GitHub MCP attack shows why sequence matters. The assistant reads a public issue carrying hidden instructions, then posts private repository content back out. Reading issues is authorized. Writing to a repository is authorized. The danger is a write that follows untrusted input, and no scope expresses that.

Meta's Agents Rule of Two exists because this cannot be patched at the model layer yet. It applies "until robustness research allows us to reliably detect and refuse prompt injection," and says an agent needing all three properties in one session should not act autonomously.

Time

Short-lived credentials limit how long a token is useful. They do not limit how long information lives. Aggregation happens after authorization: in the context window, in a summary pasted into a doc, in an assistant's memory. Monday's summary plus Tuesday's query is the same mosaic, with clean, rotated credentials both times. Rotation resets the token, not the knowledge.

Where the proxy fits

Aggrete is an open-source MCP proxy that sits between assistants and connectors. It does not compete with agent identity. It depends on it.

In HTTP mode it validates JWTs from your IdP and takes the user from the token. Upstreams marked per_user are reached with the caller's own resolved credential, so the upstream sees the actual person rather than a shared robot account. The proxy holds connector credentials itself and never forwards the caller's token upstream. That is the identity layer, done properly.

Then it asks the questions identity cannot:

QuestionAgent identityAggrete
Who is acting, on whose behalf?YesConsumes it from the IdP token
May this identity call this tool?YesYes, plus walls and hidden tools
Does this call complete a forbidden combination about the same people?Nodomain_join with entity overlap
Did this session read untrusted content before this write?NoFlow rule refuses the write
What has this person pulled across sessions and clients?NoPer-user accumulator with a window
Who owns the rule?IAM or securityThe clause owner, in coc.yaml

A rule is a clause from your code of conduct, owned by the person who wrote it:

- rule_id: COC-HR-004
  clause: >
    Personnel records, compensation or budget records, and operational rosters
    may not be combined to derive the employment status, performance, or
    planned departure of identifiable individuals.
  owner: hr-privacy@example.com
  enforce:
    - layer: accumulation
      action: deny
      type: domain_join
      domains: [hr-personnel, finance-comp, ops-rota]
      require_entity_overlap: true
      scope: user
      window: 4h

On the four-question sequence, three calls pass and the fourth is refused before the upstream is contacted, so the on-call data is never fetched:

four questions, one person
turn 1 ▸finance__headcount_plan  →  allowed
turn 2 ▸finance__budget_roles  →  allowed owner emails redacted
turn 3 ▸hr__recent_joiners  →  allowed emails redacted
turn 4 ▸ops__oncall_draft  →  denied COC-HR-004 · upstream never contacted

For order, any write after a session has read untrusted content is refused. For time, state is keyed on the token identity, so the same person working from Claude Code, Claude.ai and Cursor shares one history. Every decision is written as one hash-chained JSON line.

There is no model in the decision path, on purpose. Reviewing a 2025 paper that tested published prompt injection defenses against adaptive attackers, Willison noted the defenses were beaten so thoroughly that he doubts reliable ones will arrive soon. A rule that can be read, tested in CI and replayed from an audit log is a sturdier foundation than a classifier that can be argued with.

The two layers need each other

The dependency runs both ways. A proxy is only a control if it is the only path, and that part is an identity problem. People sign in to the proxy, the proxy signs in to the connectors, connectors accept traffic only from the proxy host, and managed client policies allow-list the proxy and nothing else. If an assistant keeps its native Drive connector, it has two roads to Drive and the policy sees one.

What neither solves

Entity extraction is the weak point: rules that join on people depend on stable IDs and emails in tool results. Post-call denial redacts, it does not un-fetch. And aggregation cannot be solved, only narrowed. Someone who spaces requests beyond the window, or paraphrases across systems the proxy does not front, gets through. The goal is to raise the cost and leave an audit trail, not to promise a ceiling.

The short version

Identity shrinks the scope. Policy governs what happens inside the scope that remains. A scoped token tells you who acted and what they could reach. A code of conduct tells you whether they should have.

Run the four-question walkthrough locally with uvx aggrete --demo, or in the browser at try.aggrete.com. For how Aggrete compares to scanners, guardrails and gateways, see the landscape post.
Open source

Deterministic policy for what AI can reach and do.

Aggrete is Apache-2.0. No model in the decision path.

Star on GitHub How it works