# Give every agent its own identity

> You cannot set authority for, bill, or review something you cannot name.

Part 14: Operating the workforce. From *Engineering Deterministic AI Coding Agents*, second edition, by Mac Anderson. Canonical page: https://macanderson.com/manual/give-every-agent-its-own-identity

A pull request lands overnight. The commit author is a shared bot account that six agents and two scripts use. The change is fine, but the review question is not about the diff. It is: which agent did this, who started it, and what was it allowed to do? If the answer takes an afternoon of reading logs, the agents are doing work that nobody in particular is accountable for.

### What parts 1 to 13 left open

The first thirteen parts moved decisions out of the model and into code: what to retrieve, what to keep in the window, which step runs next. One decision is still open, and it is the one a second team will ask about. What may this agent do in systems other people own? The same principle answers it. Decide in the system, before the model is involved, and keep the decision where a person can read it. That starts with a name.

### The familiar model and what it cannot answer

The familiar model is a shared credential. One token carries everything any agent might need, and every agent that holds it looks the same to the system on the other end. It is quick to set up. It also means three questions have no answer in the data:

-   **Which agent acted?** The target system saw the token, not the agent.
-   **On whose behalf?** The person who started the task is not in the call.
-   **Under what authority?** The token's scope is the union of every task anyone ever planned, so it says nothing about this task.

Zero trust architecture gives the general form of the fix. NIST's definition assumes no implicit trust from network location or asset ownership, and it evaluates each request against policy for the specific subject and resource.[22](https://macanderson.com/manual/sources#r22 "Rose, Borchert, Mitchell and Connelly (NIST). \"Zero Trust Architecture.\" NIST Special Publication 800-207, 2020. doi.org/10.6028/NIST.SP.800-207") An agent is a subject. It needs to be one the policy can tell apart from the other agents.

### What an agent identity holds

An identity is a record, not a credential. It answers who this is and who answers for it:

| Field | What it says | Example |
| --- | --- | --- |
| `agent_id` | A stable principal, one per agent, never reused | `agt_refund_triage` |
| `operator` | The person accountable for this agent and its runs | Dana Okafor, payments platform |
| `harness` | What runs it, and at which version | Claude Code 2.x, wrapped |
| `purpose` | One sentence a reviewer can check a run against | Triage refund failures and open a fix PR |
| `environment` | Where it may work | staging, `billing/**` |
| `status` | Enrolled, held, or retired, with a date | enrolled 2026-08-04 |

Three properties matter more than the fields. The identity is **separate from any connection credential**, so rotating a GitHub token does not change who the agent is. It **carries the initiator through**: each run records the person who started it, so "on whose behalf" is data, not inference. And it can be **revoked alone**: holding one agent does not stop the other five.

#### ◌ One shared credential

-   The target system sees one actor for every agent
-   The initiator is not recorded
-   Scope is the union of all planned tasks
-   Revoking it stops everything that uses it

#### ● One identity per agent

-   Each call names the agent that made it
-   Each run names the person who started it
-   Authority attaches to the identity (part 15)
-   One agent can be held while the others work

> **Evidence · Excess authority is a design property**
>
> OWASP's Top 10 for LLM applications lists excessive agency as its own category. It breaks the cause into three parts: excessive functionality, excessive permissions, and excessive autonomy. Each is a property of how the system around the model was built, not of the model.[23](https://macanderson.com/manual/sources#r23 "OWASP. \"Top 10 for LLM Applications 2025,\" LLM06: Excessive Agency. genai.owasp.org") The Berkeley failure taxonomy from part 9 points the same way: most recorded multi-agent failures traced to system design, including specification and verification, and the authors do not expect better models alone to fix them.[5](https://macanderson.com/manual/sources#r5 "Cemri et al. (UC Berkeley). \"Why Do Multi-Agent LLM Systems Fail?\" (MAST). NeurIPS 2025 Datasets & Benchmarks. arXiv:2503.13657")
>
> OWASP, Top 10 for LLM applications · Cemri et al., NeurIPS 2025

### Start with an inventory

Most teams cannot list their agents, because agents arrive one team at a time. The inventory is a spreadsheet before it is a system. One row per agent, the six fields above, and two more columns: which credentials it can reach today, and who would notice if it stopped. The rows with no operator are the first finding. The rows that share a credential are the second.

> **Where Oxagen fits**
>
> In Oxagen each enrolled agent is a registered principal with its own identity and an accountable operator. That identity is distinct from any connection credential. Agents built by different groups, on different harnesses, appear on one Runs page with their open requests, their spend, and their last run. Oxagen does not run the agent. A supported wrapper sits beside the harness, and the agent keeps running where it runs today.

> **Do this week**
>
> 1.  **List every agent that can write to a system.** Ask each team. Include scheduled scripts that call a model. Done is one row per agent with an operator's name in it.
> 2.  **Mark each shared credential.** For every credential, list the agents that can reach it. Any credential with more than one agent is a row in your backlog.
> 3.  **Give each agent a stable id and a one-sentence purpose.** Put the id in the commit trailer, the user agent string, or the request header, whichever the target system records.
> 4.  **Record the initiator.** Pass the id of the person who started the task into the run, and write it next to the agent id on every outbound call you log.
> 5.  **Test a single revocation.** Hold one agent in staging. Confirm that it stops and that nothing else does.

> **Measure it**
>
> -   `agents_with_operator`: agents with a named, current operator, over all agents. Anything under 1.0 is an agent nobody answers for.
> -   `agents_per_credential`: the largest number of agents that share one credential. The target is 1.
> -   `attributable_actions`: logged write actions that carry both an agent id and an initiator, over all logged write actions. Track it weekly. It should rise as wrappers roll out.

> **Takeaway**
>
> Authority, budget, and review all attach to a name. Give each agent its own identity and a person who answers for it, and keep both apart from the credentials it works through.
