The Foundational Problem of Agent Identity

By Dylan47 min read

In traditional systems, APIs, SaaS products, and internal business systems could already be accessed programmatically. Service accounts, OAuth clients, API keys, CI/CD runners, RPA jobs, ETL jobs, and third-party integrations can all act as visitors that call external systems. Traditional IAM can already create identities for these programs, issue tokens, assign scopes, and produce audit records.

So this article does not treat "agent identity" as a self-evidently new object. An agent system is still, first of all, a program system. It can use a user session, a service account, an OAuth client, an API key, or a workload identity. It can also be brought under authentication, authorization, scopes, consent, token lifecycle management, and audit. As long as the problem remains "which subject calls which resource", traditional IAM already has mature models.

If we only look at visitor types, many things in an agent system map directly back to traditional IAM:

Access pattern in an agent system Existing object in traditional IAM Boundary already handled
Acting on behalf of a user User session, delegated OAuth token Login, MFA, consent, scope, audit
Acting as a program Service account, workload identity Secrets, tokens, roles, least privilege, runtime logs
Calling a third-party API OAuth client, API key Client registration, authorization scopes, token lifecycle
Running automation CI/CD runner, RPA, ETL, scheduled job Fixed permissions, fixed triggers, fixed actions, runtime logs

This table shows that the problem of agent identity cannot be established merely by "giving the agent an account." If agent identity is only a renamed user identity, service account, OAuth client, or API key, then it has no new theoretical content. The question of this article is: what structural difference appears between agent systems and non-agent systems, such that agent identity cannot be reduced to those traditional identity objects?

By "agent identity", I do not mean an isolated account. I mean the way the same runtime control subject represents a user, application, or service identity while exercising control over multiple permission domains that used to be isolated, and the way authorization, constraints, and audit responsibility must be attached to the composition paths generated by that runtime. Only after this structural difference is clear can later discussions of Agent IAM, runtime approval, tool authorization, and audit trails have a stable starting point.

The core conclusion is this: the foundational problem of agent identity is that multiple permission domains, which were previously isolated and secured through reviewed path languages and least privilege, are placed under the same composable runtime control subject. This means "each local action is legal" and "each permission domain is individually safe" are no longer closed under composition. In other words, an agent runtime may generate a path made of legal actions, while that full path has never been reviewed as a whole and may violate task delegation, separation of duties, or data-flow boundaries. Traditional IAM's subject-action-resource authorization remains foundational, but mainstream deployments usually do not include the task, runtime history, data provenance, and cross-tool state in the same authorization decision. New Agent IAM therefore needs to model task, runtime path, reviewed path, and data flow as objects of authorization, approval, constraint, and audit.

A simple example: a contract system allows a user to read contract C-42, and the email system also allows that user to send email. Traditional IAM can separately answer "can this user read this contract?" and "can this user send this email?" Agent IAM has to answer another question: under the current task, after reading C-42, is the same runtime allowed to send content derived from it to this recipient? The risk is not in either single-step action. It is in the data-carrying path formed by composing the two actions.

Clarification: assurance and review are not identical
In this article, reviewed means that a path has gone through engineering review, permission design, approval flow, or test coverage, giving us evidence for a safety guarantee. Whether something is actually safe is determined by whether it satisfies business policy; this is not strictly identical to whether it was reviewed. A path outside the review set lacks assurance, but is not necessarily dangerous. Conversely, a reviewed path still depends on its assumptions, configuration, and environment continuing to hold.

Clarification: permission domains are not physical system boundaries
A cross-domain path does not have to cross SaaS products, APIs, or organizations. A single SaaS product may contain a contract data domain, an email-sending domain, an approval responsibility domain, and an external-sharing domain. Conversely, if a problem happens entirely inside one permission domain, such as a missing ACL, overbroad permissions, or a retrieval layer without permission trimming, it is still a traditional IAM, data governance, or application security problem, not the new Agent IAM problem defined here.

Traditional Programmatic Access

Traditional programmatic access is not low risk. Traditional programs have vulnerabilities, misconfigurations, overbroad permissions, SSRF, log leaks, and supply-chain risk. The important engineering property of traditional automation is not "fixed paths are safe." It is this: the external-effect paths are usually constrained by design-time structure, so they can be reviewed as a whole through code review, permission design, testing, approval, and separation-of-duties checks.

Here, a program path means the sequence of operations from input to external effect. A report export job might have this path:

read orders -> aggregate fields -> generate CSV -> write to internal object storage

A contract synchronization service might have this path:

read contract metadata -> normalize fields -> write to search index

A CI/CD release script might have this path:

read code -> build image -> push artifact -> deploy to target environment

These paths may have branches, retries, and configuration switches. They may also use a rule engine or workflow configuration to choose the next step dynamically. The key is not that there is only one fixed path. The key is that the path set is usually defined before deployment by code, configuration, approval flows, or integration boundaries, and can be covered by the review process. Because the path set is reviewable, IAM can shrink permissions around those paths.

Automation Reviewed path set Least-privilege boundary
Report export job Read orders, generate file, write to internal storage read:orders, write:internal_bucket
Contract sync service Read contract metadata, write to search index read:contracts, write:search_index
Customer support ticket sync Read CRM updates, create tickets read:crm_case, write:ticket
CI/CD release script Pull code, build image, deploy service repo read, artifact write, deploy target

The point of this table is not "traditional programs have no risk", nor "fixed paths are naturally safe." The point is: a constrained path set makes permission needs enumerable, reviewable, testable, and reducible. If the reviewed path for a report job does not include sending email, writing orders, or external network egress, then least privilege can be configured around that path set. Even if the job has a logic bug, it is difficult for it to jump outside its capability envelope and approve contracts, delete customers, or send sensitive material to an external person.

So the security boundary of traditional automation can be written as:

Traditional automation security boundary  reviewed path language+least privilege+stable identity boundary+input validation, code review, runtime isolation, and audit\begin{aligned} \text{Traditional automation security boundary} \triangleq\;& \text{reviewed path language} + \text{least privilege} + \text{stable identity boundary} \\ &+ \text{input validation, code review, runtime isolation, and audit} \end{aligned}

Program paths should not be understood as "programs are naturally trustworthy." A more precise statement is: constrained, reviewable path sets make least privilege an operational engineering fact. IAM does not guarantee safety by itself. It compresses the program's capability space together with the reviewed path language.

The Formal Boundary of Agent Systems

This article is not defining every agent architecture. It is delimiting the problem domain of Agent IAM. A Q&A bot, document summarizer, or offline analysis tool may use an LLM and still have data leakage, prompt injection, unauthorized retrieval, missing ACLs, hallucinations, or output quality problems. But if those risks happen inside a single permission domain, they are essentially isomorphic to single-domain vulnerabilities in non-agent systems.

For example, if a search system does not carry document ACLs into indexing and query filtering, it will cause unauthorized retrieval. If a summarization service has an overbroad database read permission, it may leak data that should not have been exposed. These problems do not require an agent composition path to explain them. I exclude these raw permission-domain failures as a premise: before discussing Agent IAM, assume that each permission domain's local authorization and safety controls have already been defined within its own boundary using traditional IAM and AppSec models. The question here is why those original guarantees do not automatically extend to composition paths when domains that used to be separately constrained by local safety boundaries are composed by the same runtime control subject.

The agent systems that trigger the identity-modeling problem usually have three engineering properties:

Condition Meaning Shape outside this problem domain
External effects Can read or write external systems, SaaS products, databases, email, tickets, files, or business objects Only queries, summarizes, or generates text within a single permission domain
Tool set Has multiple selectable tools, APIs, connectors, or operations A single resource, a single API wrapper, or fixed capability inside one permission domain
Composable path generation Tool choice, call order, and parameters are decided by the goal, context, model judgment, and tool returns Fixed workflow, single API wrapper, or reviewed state machine

These three conditions are still surface features, not the essential definition. A runtime path-generating system can be safe if it only selects branches inside a reviewed state machine, or if every runtime path is proven by a policy engine to remain inside the reviewed path set. The identity problem appears at the point where multiple permission domains that used to be isolated are composed by the same control subject, and the resulting path has not been reviewed as a whole by the original least-privilege design, code review, separation-of-duties checks, and data-flow review.

So the following formalization does not start by listing agent architecture components. It directly describes the relationship this article analyzes: which permission domains are controlled by the same control subject, which paths it can generate, and whether those paths enter the reviewed path language.

The formulas below are modeling language, not theorems derived from axioms. Wherever I use \triangleq, I am defining an object, set, or predicate. Wherever I use \subseteq, I am describing coverage or constraint between path sets. Wherever I use \exists, I am stating a risk condition. Wherever I use p, pP\forall p,\ p\models P, I am stating a safety objective. With that distinction, the reader should evaluate whether the definitions capture the problem, not read them as conclusions that require proof.

To avoid dangling symbols, define a few basic objects first. DD is the set of permission domains under discussion. II is the set of identity entry points exposed by those domains. The subscript jj identifies one permission domain and its corresponding identity entry point. CC is the control subject in one run. τ\tau is the current task. pp is an action path or event trace. If CC or τ\tau is omitted later, the context is either fixed or the discussion is about the general shape.

Define a permission domain:

djD,ijI,dj(systemj,ij,A(ij),boundaryj)d_j \in D,\quad i_j \in I,\quad d_j \triangleq (\mathrm{system}_j, i_j, A(i_j), \mathrm{boundary}_j)

Here, systemj\mathrm{system}_j is the system or resource boundary being accessed. iji_j is the identity entry point into that system. A(ij)A(i_j) is the set of actions allowed through that identity entry point. boundaryj\mathrm{boundary}_j is that system's own data, responsibility, or organizational boundary.

To unify "actions on an identity entry point" and "actions in a permission domain", define:

A(dj)A(ij)A(d_j) \triangleq A(i_j)

In other words, A(dj)A(d_j) is the action set that permission domain djd_j exposes to the control subject through identity entry point iji_j.

Now define which identity entry points the runtime control subject CC can exercise. Let ICI_C be the set of identity entry points that CC can directly use at runtime:

IC{ijIcan_use(C,ij)}I_C \triangleq \{i_j \in I \mid \mathrm{can\_use}(C, i_j)\}

can_use(C,ij)\mathrm{can\_use}(C, i_j) means that, in a run, CC can initiate a tool call through identity entry point iji_j without another independent human decision or independent system approval. The control subject's effective domain set is:

DC{djDijIC}D_C \triangleq \{d_j \in D \mid i_j \in I_C\}

DCD_C is the set of permission domains that control subject CC can actually exercise at runtime. The cross-domain composition problem in this article appears when DCD_C includes multiple permission domains that were previously isolated by different programs, functions, identity boundaries, or organizational policies.

Aeff(C)ijICA(ij)A_{\mathrm{eff}}(C) \triangleq \bigcup_{i_j \in I_C} A(i_j)

Aeff(C)A_{\mathrm{eff}}(C) is the set of single-step actions that CC can invoke. It describes the menu, not the process. For example:

{read_contract,send_email}Aeff(C)\{\mathrm{read\_contract}, \mathrm{send\_email}\} \subseteq A_{\mathrm{eff}}(C)

This only says that CC can theoretically read a contract and send email. It does not say that it can, should, or is allowed to execute arbitrary sequences of those actions. In the contract-summary example, the symbols map to concrete objects like this:

Symbol Object in the example
CC Current agent runtime
τ\tau "Read contract C-42, generate a summary, and send it to legal@corp.com"
d1d_1 Contract permission domain
i1i_1 User delegated token that can read contracts
A(i1)A(i_1) Contract-reading actions such as read_contract(C-42)
d2d_2 Email permission domain
i2i_2 User or application identity entry point that can send email
A(i2)A(i_2) Email-sending actions such as send_email(to, body)
ICI_C Identity entry points directly usable by the agent runtime in this run
Aeff(C)A_{\mathrm{eff}}(C) The combined single-step action menu formed by contract reads and email sends

The superscript * comes from Kleene closure in formal language theory. It means "all finite sequences composed of elements from this set." So Aeff(C)A_{\mathrm{eff}}(C)^* is the theoretical full path space, for example:

[]
[read_contract]
[send_email]
[read_contract, send_email]
[send_email, read_contract]
[read_contract, read_contract]
...

This set is intentionally large. It only says "if we look only at the action alphabet, which finite sequences can be written down." It does not say that all those sequences can be generated by the runtime, nor that they satisfy tool preconditions, data dependencies, task constraints, or safety policies. Real systems usually generate only a tiny subset of this space. So the path language that control subject CC may actually generate or execute is:

L(C)Aeff(C)L(C) \subseteq A_{\mathrm{eff}}(C)^*

L(C)L(C) describes which local actions CC may compose into external effects under a given runtime, tool visibility, context, policy, and tool-return constraints. It is a subset of Aeff(C)A_{\mathrm{eff}}(C)^*: every actual path must be composed of actions in Aeff(C)A_{\mathrm{eff}}(C), but not every permutation of those actions becomes an actual path. L(C)L(C) is not by itself a sufficient condition for danger. A runtime-generated path language can be safe as long as it is constrained inside the reviewed path language, or every path receives equivalent review before execution. The key is not "runtime generation." The key is whether the composition path has a source of safety assurance.

Let Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau) denote the path language that has been reviewed as a whole, at design time or before execution, in the context of control subject CC and task τ\tau. Review sources include constrained program path sets, code review, least-privilege configuration, integration approval, separation-of-duties policy, data-flow policy, and testing. When the task is not under discussion, I will abbreviate this as Lreviewed(C)L_{\mathrm{reviewed}}(C) or LreviewedL_{\mathrm{reviewed}}. If Assured(p,C,τ)\mathrm{Assured}(p,C,\tau) means the existing engineering process can provide evidence of safety assurance for path pp in this context, then traditional systems usually support safety claims only for paths inside Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau):

pLreviewed(C,τ)Assured(p,C,τ)p \in L_{\mathrm{reviewed}}(C,\tau) \Rightarrow \mathrm{Assured}(p,C,\tau)

More precisely, Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau) is the set of paths whose safety has been proven or accepted by the engineering process. If a path is outside Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau), we cannot infer from the original process that it is assured. The fact that every action inside a path is locally legal does not automatically mean the whole path belongs to Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau).

In the contract-summary task, two paths can use the same local capabilities but receive different path-level judgments:

Path Can assurance be inferred from the reviewed path language? Reason
[read_contract(C-42), send_email(legal@corp.com, summary)] Possibly Recipient, content shape, and purpose match the current task
[read_contract(C-42), send_email(external@gmail.com, full contract)] Not by default Each single-step action may be locally legal, but the full path contains an unauthorized data egress

This object lets us describe a safe shape of traditional programmatic access. A non-agent control subject may also have a broad permission range: it may access multiple APIs, hold multiple scopes, or cover a complete business process. A larger permission range does not automatically mean multiple previously isolated permission domains have been crossed. The key is whether those permissions still serve the same set of reviewed paths. For traditional automation covered by reviewed paths, we can write:

Lnon-agent(C)Lreviewed(C)L_{\mathrm{non\text{-}agent}}(C) \subseteq L_{\mathrm{reviewed}}(C)

Here Lnon-agent(C)L_{\mathrm{non\text{-}agent}}(C) is the set of paths control subject CC may actually execute, and Lreviewed(C)L_{\mathrm{reviewed}}(C) is the path set covered by code, configuration, workflow, approval, testing, and organizational policy. A traditional program may access multiple APIs and have conditional branches, retries, and configuration switches. As long as the composition paths it may actually execute remain inside Lreviewed(C)L_{\mathrm{reviewed}}(C), the safety review covers complete paths rather than only single-step actions. Fixed paths, constrained workflows, and rule engines are common ways to generate Lreviewed(C)L_{\mathrm{reviewed}}(C).

Common traditional automation can be written further as:

Lnon-agentLdesignL_{\mathrm{non\text{-}agent}} \subseteq L_{\mathrm{design}}

LdesignL_{\mathrm{design}} is a common source of LreviewedL_{\mathrm{reviewed}}: a path set that can be enumerated, reviewed, and tested at design time. Traditional programs may have multiple permission domains, conditional branches, retries, configuration switches, and multiple API calls. As long as their possible action sequences remain constrained by LdesignL_{\mathrm{design}}, the safety review covers the full path, not only each single-step action.

The distinction on the agent side is also not whether the path is fixed. Dynamic branches, rule engines, and workflow selection can exist in traditional automation. If they still fall inside Lreviewed(C)L_{\mathrm{reviewed}}(C), they do not constitute the identity problem discussed here. The agent identity problem requires two conditions at the same time: the same runtime control subject can composably exercise multiple permission domains that used to be isolated; and it may generate cross-domain composition paths that are not covered by whole-path review. For task τ\tau, the path language generated by an agent runtime can be written as:

Lagent(C,τ)GeneratePath(τ,Aeff(C),context,tool_results,policy)L_{\mathrm{agent}}(C,\tau) \triangleq \mathrm{GeneratePath}( \tau, A_{\mathrm{eff}}(C), \mathrm{context}, \mathrm{tool\_results}, \mathrm{policy} )

GeneratePath\mathrm{GeneratePath} is not the name of a concrete algorithm. It abstracts over agent runtime planning, tool selection, parameter generation, and result feedback. context\mathrm{context} is the current context. tool_results\mathrm{tool\_results} are returned tool results. policy\mathrm{policy} is the set of policy hints or constraints visible to the runtime. Truly mandatory path review is still expressed by Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau), the runtime authorization predicate, and runtime enforcement mechanisms. Runtime path generation can be safe. The essential problem is that when DCD_C contains multiple previously isolated permission domains, GeneratePath\mathrm{GeneratePath} may generate cross-domain composition paths outside the review set, and those paths may not belong to LreviewedL_{\mathrm{reviewed}}.

If PτP_\tau denotes the safety policy of the current task, the final safety goal on the agent side can be written as:

pLagent(C,τ),pPτ\forall p \in L_{\mathrm{agent}}(C,\tau),\quad p \models P_\tau

Here pPτp \models P_\tau means path pp satisfies task delegation, resource authorization, separation-of-duties, and data-flow constraints.

pLagent(C,τ):CrossDomain(p)pLreviewed(C,τ)\exists p \in L_{\mathrm{agent}}(C,\tau): \mathrm{CrossDomain}(p) \land p \notin L_{\mathrm{reviewed}}(C,\tau)

CrossDomain(p)\mathrm{CrossDomain}(p) means that path pp crosses at least two permission domains that were previously governed by different permission policies, data boundaries, separation-of-duties requirements, or reviewed path constraints. It does not require the path to cross physical systems; a single enterprise suite or SaaS product can contain multiple such permission domains. This existential condition excludes cases where a single permission domain's own controls failed, and it reaches the core difference: an agent places actions that were previously distributed across multiple reviewed path languages under one composable control subject, making unreviewed composition paths possible.

So the formal difference between agent and non-agent systems is not a component checklist. It is the relationship between path sets and safety assurance:

Lnon-agent(C)Lreviewed(C)L_{\mathrm{non\text{-}agent}}(C) \subseteq L_{\mathrm{reviewed}}(C) pLagent(C,τ):CrossDomain(p)pLreviewed(C,τ)\exists p \in L_{\mathrm{agent}}(C,\tau): \mathrm{CrossDomain}(p) \land p \notin L_{\mathrm{reviewed}}(C,\tau)

The first expression says that the external-effect paths of a non-agent system are covered by the reviewed language. The second says that an agent runtime may generate a path that crosses permission domains but has not entered the reviewed language. Only the second case creates the new IAM problem discussed here. More rigorously, multiple permission domains in a non-agent system are not safe merely because "isolation exists." They are safe because each domain is usually exposed only to certain reviewed paths:

djused byLreviewed(j)d_j \xrightarrow{\text{used by}} L_{\mathrm{reviewed}}^{(j)}

Lreviewed(j)L_{\mathrm{reviewed}}^{(j)} is the local path language reviewed around permission domain djd_j.

Cross-system integration can also be safe. It needs to form its own reviewed integration path:

pintegrationLreviewed(integration)p_{\mathrm{integration}} \in L_{\mathrm{reviewed}}^{(\mathrm{integration})}

pintegrationp_{\mathrm{integration}} is a concrete cross-system integration path, and Lreviewed(integration)L_{\mathrm{reviewed}}^{(\mathrm{integration})} is the path language separately established and reviewed for that type of integration.

The essential difference with agents is that they place multiple permission domains, each previously constrained by its own Lreviewed(j)L_{\mathrm{reviewed}}^{(j)}, into the same CruntimeC_{\mathrm{runtime}}. Here CruntimeC_{\mathrm{runtime}} is the runtime control subject in a concrete agent run, an instance of the earlier control subject CC. The system can no longer infer "any cross-domain composition path is safe" from "each permission domain is safe on its own." The new IAM problem is precisely to rebuild task-level, path-level, and data-flow-level review and constraints for those cross-domain composition paths.

The path set of a traditional program can be written as:

Lnon-agentReviewedByDesign(code,config,workflow,policy)L_{\mathrm{non\text{-}agent}} \triangleq \mathrm{ReviewedByDesign}(\mathrm{code}, \mathrm{config}, \mathrm{workflow}, \mathrm{policy})

ReviewedByDesign\mathrm{ReviewedByDesign} is not an algorithm name. It means the path set jointly limited by code, configuration, workflow, and policy, and therefore reviewable by an engineering process. input\mathrm{input} and config\mathrm{config} can influence branches, but the external systems the program will access, the operations it will call, and the rough direction of data flow are usually constrained by code, configuration, workflow, and policy, and can be reviewed as a path set.

Let TT be the set of tools visible at runtime; later we will expand the structure of each tool in TT. The earlier GeneratePath\mathrm{GeneratePath} can be understood as a planner producing paths from a goal, context, history, tool results, tool set, and policy:

planner(goal,context,history,tool_results,T,policy)\mathrm{planner}(\mathrm{goal}, \mathrm{context}, \mathrm{history}, \mathrm{tool\_results}, T, \mathrm{policy})

Here TT is the call surface exposed to the agent by DCD_C. Lagent(C,τ)L_{\mathrm{agent}}(C,\tau) is the path set generated or selected by the runtime planner. Whether it is safe depends on whether these paths are further constrained into Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau), not on the fact that they were generated at runtime.

RAG is a useful boundary example. A system may be called an agent in product copy and may use an LLM plus vector retrieval, but it does not necessarily enter the identity problem domain described here. The key is not whether it is RAG. The key is whether it places multiple permission domains and external effects into the same composable runtime and generates unreviewed cross-domain composition paths.

Read-only RAG with user-permission trimming is closer to a traditional reviewed path. Let Lrag-readonly(C)L_{\mathrm{rag\text{-}readonly}}(C) denote the retrieval-and-answer paths that control subject CC may execute in a read-only RAG system:

Lrag-readonly(C)Lreviewed(C)L_{\mathrm{rag\text{-}readonly}}(C) \subseteq L_{\mathrm{reviewed}}(C)

Microsoft 365 Copilot is a real-world boundary example. Microsoft 365 Copilot uses Microsoft Graph to access organizational data such as email, documents, meetings, and chats that the user is authorized to access. Official documentation says it only presents organizational data for which the user has at least view permission, and that Semantic Index respects user-identity-based access boundaries.1 Even if this kind of system looks like an "enterprise RAG agent", as long as behavior is limited to read-only retrieval and answers, and retrieval results are strictly trimmed by the current user's permissions, the CFO and an ordinary finance employee see different corpora. The core remains traditional data access control and retrieval permission trimming.

RAG without ACLs is another case. The Azure AI Search security filter pattern requires storing the user's or group's principal identifier in the index and using a filter at query time to trim results; the documentation example says query results return only documents for which the requester has read access.2 If a RAG system puts finance documents, HR documents, and contract documents into one vector index but does not carry document ACLs into indexing and query filtering, then the CFO and ordinary finance employees may retrieve the same materials. This is serious, but it is essentially authorization missing in the retrieval layer, not the new agent identity problem defined here. The fix is document-level authorization, security filters, and permission trimming, not first inventing Agent IAM.

RAG enters this article's problem domain when retrieval results flow into later tool calls and form cross-domain composition paths. Let Lrag-agentic(C,τ)L_{\mathrm{rag\text{-}agentic}}(C,\tau) denote the path language that control subject CC may generate under task τ\tau after sending retrieval results onward into tools such as email, CRM, approvals, tickets, or payments:

pLrag-agentic(C,τ):CrossDomain(p)pLreviewed(C,τ)\exists p \in L_{\mathrm{rag\text{-}agentic}}(C,\tau): \mathrm{CrossDomain}(p) \land p \notin L_{\mathrm{reviewed}}(C,\tau)

For example, the system first retrieves contracts, email, or financial data, and then the same runtime decides whether to send email, create a ticket, update CRM, initiate an approval, or call a payment API. Now the issue is not only "can the current user see this document?" It is "can data from this document enter later tools, who can it be sent to, which system can it be written into, and does that match the current task?" At that point the problem moves from permission trimming into cross-domain composition path governance.

System shape Formal location In this article's problem domain? Boundary reason
Read-only RAG with retrieval results trimmed by user permissions Lrag-readonly(C)Lreviewed(C)L_{\mathrm{rag\text{-}readonly}}(C) \subseteq L_{\mathrm{reviewed}}(C) No Traditional IAM, ACLs, and retrieval permission trimming can define the visible data range
RAG index without ACL / permission trimming Authorization-defect RAG Not a new agent identity problem, but a serious authorization defect The retrieval layer bypasses or loses traditional authorization boundaries
Agentic RAG: retrieval results enter tools such as email, CRM, approvals, tickets, and payments pLrag-agentic(C,τ):CrossDomain(p)pLreviewed(C,τ)\exists p \in L_{\mathrm{rag\text{-}agentic}}(C,\tau): \mathrm{CrossDomain}(p) \land p \notin L_{\mathrm{reviewed}}(C,\tau) Yes The same runtime combines read capability, write capability, and cross-domain or cross-system data flow; the composition path needs review

So far, to emphasize path composition, I have abbreviated paths as action sequences [a1,a2,,an][a_1,a_2,\ldots,a_n]. Strictly speaking, the object Agent IAM must judge is not a bare action name, but an event trace with parameters, resources, data provenance, external effects, and time. An agent run can be written as:

run[event1,event2,,eventn]\mathrm{run} \triangleq [\mathrm{event}_1, \mathrm{event}_2, \ldots, \mathrm{event}_n] eventk(runk,taskk,actork,identityk,toolk,operationk,resourcek,argsk,provenancek,effectk,timek)\mathrm{event}_k \triangleq ( \mathrm{run}_k, \mathrm{task}_k, \mathrm{actor}_k, \mathrm{identity}_k, \mathrm{tool}_k, \mathrm{operation}_k, \mathrm{resource}_k, \mathrm{args}_k, \mathrm{provenance}_k, \mathrm{effect}_k, \mathrm{time}_k )
Symbol Meaning
runk\mathrm{run}_k The agent run this event belongs to; binds task, policy, and audit context
taskk\mathrm{task}_k The current user delegation or system task
actork\mathrm{actor}_k The user, agent runtime, or service principal that initiated or controls this run
toolk\mathrm{tool}_k The tool, connector, API, or external-system capability called at step kk
identityk\mathrm{identity}_k The user identity, application identity, service identity, or connector credential used at this step
operationk\mathrm{operation}_k The concrete action, such as reading a contract, sending email, updating CRM, or creating an approval
resourcek\mathrm{resource}_k The resource object accessed or modified, such as a contract, email, ticket, or repository
argsk\mathrm{args}_k Call parameters such as recipient, amount, attachment, or filter condition
provenancek\mathrm{provenance}_k Input data source, sensitivity level, and provenance of prior tool outputs
effectk\mathrm{effect}_k The external effect produced by this step, such as reading data, writing data, sending a message, or triggering a workflow
timek\mathrm{time}_k Event time; used to express expiration, order, cumulative state, and audit relationships

For example, email.send is not a sufficiently fine-grained authorization object. email.send(to=legal@corp.com, body=redacted summary) and email.send(to=external@example.com, body=full contract) have the same operation, but different resources, parameters, data provenance, and external effects. When I continue to use the word "path" below, it is shorthand for this kind of event trace.

Let LdesignL_{\mathrm{design}} be the set of program paths that can be enumerated, reviewed, and tested at design time: the set of action sequences allowed by design and covered by the engineering process. Traditional program paths can have conditional branches, but those branches usually already fall inside LdesignL_{\mathrm{design}}. Agent runtime paths, by contrast, may be generated by a planner from the task, context, tool returns, and policy. This does not directly imply "unsafe." It only implies that we cannot assume these paths already fall inside the reviewed path set.

That gives the first formal judgment of this article:

Lnon-agentLdesignLreviewedL_{\mathrm{non\text{-}agent}} \subseteq L_{\mathrm{design}} \subseteq L_{\mathrm{reviewed}} Lagent(C,τ)Lreviewed(C,τ)requires additional proof or runtime reviewL_{\mathrm{agent}}(C,\tau) \subseteq L_{\mathrm{reviewed}}(C,\tau) \quad \text{requires additional proof or runtime review}

This means dynamic path generation only creates an additional review requirement. It is not sufficient by itself to create the identity problem discussed here. Traditional systems may also branch dynamically based on rule engines, user input, or queue messages. Agent systems can also use strict runtime verification to ensure Lagent(C,τ)Lreviewed(C,τ)L_{\mathrm{agent}}(C,\tau) \subseteq L_{\mathrm{reviewed}}(C,\tau). The identity problem truly appears because multiple permission domains, tool capabilities, and external effects that used to be separated are placed inside the same runtime control subject, and the composition path does not automatically fall into the reviewed path language.

From Fixed System Function to Runtime Function Scope

Traditional programmatic systems usually correspond to a relatively closed business function. Here, a "system" does not have to be a single process, script, or service. It may be a group of services, workflows, queue jobs, connectors, credential configurations, and external API calls. The function of a contract indexing system is to synchronize contracts into a search index. The function of a report export system is to read orders and generate internal reports. The function of an email notification system is to read approved notification content and send it to allowed recipients. These systems may call multiple external systems and have branches, retries, and configuration switches. The key is not whether they connect to external systems. The key is that these calls jointly serve a business function that was determined before deployment and can be reviewed as a whole.

The fixed nature of an agent lies in its runtime meta-capability, not in a stable business function. A real agent can have a fixed meta-function: receive a goal, then select, compose, and execute operations from a tool set. But that meta-function is not itself a stable business function. Summarizing a contract, sending email, creating a ticket, and modifying CRM are not functions that the agent temporarily becomes after the task arrives. They are different reachable behaviors instantiated from its original meta-capability under different tasks and tool environments. A task is not selecting a branch inside a fixed business function. It is selecting a path inside a runtime function scope.

This also shows why an agent's function boundary cannot be inferred from a product label alone. A tool may be named a coding agent, but what it actually exposes to the runtime may be a more general set of meta-capabilities: understand a goal, read materials, generate code or documents, call external tools, and continue planning from returned results. If an enterprise connects that tool to finance systems, requirement-management platforms, testing platforms, email, or approval systems, the function instantiated in one concrete task may no longer be "write code." It may be financial analysis, report generation, process advancement, requirement synchronization, or test coordination.

So an agent's runtime function scope is not determined only by "what kind of assistant it was originally designed to be." It is jointly determined by the current task, tool set, controllable identity entry points, context, and runtime policy:

FunctionScope(C,τ)Instantiate(τ,T,IC,context,policy)\mathrm{FunctionScope}(C,\tau) \triangleq \mathrm{Instantiate}(\tau,T,I_C,\mathrm{context},\mathrm{policy})

FunctionScope(C,τ)\mathrm{FunctionScope}(C,\tau) is the function scope actually instantiated by control subject CC under task τ\tau. TT is the tool set visible at runtime. ICI_C is the set of identity entry points controllable by CC. Instantiate\mathrm{Instantiate} is not an algorithm name; it denotes the process by which task, tools, identity entry points, context, and policy jointly shrink the function scope of this run. The problem is not that these functions are necessarily unsafe. The problem is that these function boundaries are not stably bound before deployment to a set of reviewed path languages in the way traditional programmatic systems usually are. They must be shrunk at runtime into the path language allowed by the current task.

This changes the shape of the authorization question. For a traditional programmatic system, the question is:

What permissions does this programmatic system need, at most, to complete all of its fixed system function?

For an agent, the question is:

What function scopes can this agent instantiate under the current tool and identity-entry environment?

For this particular task, which constrained function slice should be allowed?

The full derivation is:

  1. Traditional system safety guarantees usually apply to reviewed path languages, not to arbitrary combinations of permission sets.
  2. Fixed system functions or constrained workflows make path sets enumerable, understandable, testable, and reviewable.
  3. Permission domains can be configured with least privilege, code review, and separation-of-duties checks around those reviewed paths.
  4. Multiple traditional systems can each be safe because their permission domains are respectively constrained by their own reviewed path languages.
  5. A real agent system places multiple previously isolated permission domains under the same runtime control subject.
  6. That control subject can generate cross-domain action sequences based on the task.
  7. If those composition paths do not fall inside the reviewed path language, the original guarantees of each permission domain do not automatically transfer to the composition path.
  8. Traditional IAM's single-access judgment usually does not carry enough task, state, and data-provenance context to cover this "locally legal but globally unreviewed" path risk.

There is an important boundary here. In pure logic, dynamic branching or dynamic path selection does not necessarily imply multiple systems and does not necessarily imply insecurity. A system that dynamically selects endpoints inside a single API can also have runtime path variation. If those endpoint choices are covered by a state machine, schema, policy, or tests, it can still fall inside LreviewedL_{\mathrm{reviewed}}. The identity problem discussed here appears only when multiple permission boundaries are placed under the same control subject and generate unreviewed cross-domain composition paths.

The systems that truly enter this problem domain are different: to complete open-ended tasks, they put multiple previously separated permission domains, tool capabilities, or external effects into the same tool set. Microsoft Copilot Studio's custom agent documentation is a real example. Tools can let an agent interact with external systems, including sending email with Office 365 Outlook, reading and writing Dataverse, and reading and writing Teams; generative orchestration can automatically select the right tool; tool sources can include Power Platform connectors, REST APIs, MCP servers, or computer use.3 OpenAI GPTs have a similar structure: GPTs can enable apps or actions, and actions connect to developer-defined external APIs to retrieve data or trigger external-system effects.45

This shows that real-world agent platforms are putting multiple external capabilities into the same runtime selection surface. The problem is not imaginary.

We can formalize the structure as:

T{t1,t2,,tm}T \triangleq \{t_1, t_2, \ldots, t_m\} ti(domaini,operationi,credentiali,scopei,effecti)t_i \triangleq (\mathrm{domain}_i, \mathrm{operation}_i, \mathrm{credential}_i, \mathrm{scope}_i, \mathrm{effect}_i)

domaini\mathrm{domain}_i is the system or permission boundary the tool belongs to, such as Outlook, Teams, Dataverse, Salesforce, GitHub, a contract system, or an internal approval system. operationi\mathrm{operation}_i is the operation exposed by the tool, such as read, write, send, create approval, or trigger workflow. credentiali\mathrm{credential}_i is the identity entry point required to call the tool: user OAuth token, maker-provided credentials, service account, API key, or delegated token. scopei\mathrm{scope}_i is the action range allowed by that identity entry point or tool configuration. effecti\mathrm{effect}_i is the external effect the tool call may produce, such as reading data, writing records, sending outbound messages, or starting a business process.

The key is not just "many identities." An agent may have only one OAuth identity and still hold contracts.read and email.send; it still has composition risk. An agent may also use multiple identities across different SaaS products; if all of them are unconditionally controlled by the same runtime, the effect is similar. The decisive condition is: are multiple permission domains that were previously isolated placed under the same runtime control subject, and can that subject generate cross-domain composition paths that were not reviewed as a whole?

Using the earlier definitions, ICI_C is the set of identity entry points controllable by control subject CC at runtime, and Aeff(C)A_{\mathrm{eff}}(C) is the set of all actions CC can theoretically call directly. "Control" here does not mean ownership. It means runtime control: in one agent run, CC can directly choose an identity entry point to call a tool without another independent human decision or independent system approval. Aeff(C)A_{\mathrm{eff}}(C) only describes total capability. It does not describe whether all those capabilities should be opened for a particular task, nor whether the actions can safely be chained into one path.

The more important idea is the task slice. Let the current task be τ\tau, and let Atask(τ)A_{\mathrm{task}}(\tau) be the action set actually allowed for that task. This set cannot be inferred only from one natural-language user instruction. It should be the result of multiple constraints shrinking the space together:

Atask(τ)Adelegated(τ)AresourceAtoolAorgAruntimeA_{\mathrm{task}}(\tau) \triangleq A_{\mathrm{delegated}}(\tau) \cap A_{\mathrm{resource}} \cap A_{\mathrm{tool}} \cap A_{\mathrm{org}} \cap A_{\mathrm{runtime}}

Adelegated(τ)A_{\mathrm{delegated}}(\tau) is the action range explicitly or implicitly delegated by the user in the current task. AresourceA_{\mathrm{resource}} is the action range allowed by the resource system itself, such as API scopes, object permissions, or resource-owner policy. AtoolA_{\mathrm{tool}} is tool-layer visibility and call policy. AorgA_{\mathrm{org}} is organizational policy, such as separation of duties, DLP, external recipient restrictions, or approval requirements. AruntimeA_{\mathrm{runtime}} is runtime temporary constraint, such as user confirmation, session policy, step-level approval, or the safety policy of the current run.

This formula is simplified notation. Strictly speaking, user delegation, resource permissions, organizational policy, approval requirements, and runtime state are not all the same kind of static "action set." They are closer to policy predicates evaluated over the current state ss, candidate event eke_k, task τ\tau, and delegation chain Δ\Delta. Here ss is the current state of the agent run, such as data labels already read, cumulative amount, approval state, and executed steps. eke_k is the kk-th candidate event, the earlier tool call with parameters, resource, provenance, and external effect. Δ\Delta is the delegation chain, such as user, application, agent runtime, connector, and resource server in an on-behalf-of relationship. The set-intersection notation expresses that these constraints jointly shrink the executable event space for this run:

Permit(s,ek,τ,Δ)PdelegationPresourcePtoolPorgPruntime\mathrm{Permit}(s,e_k,\tau,\Delta) \triangleq P_{\mathrm{delegation}} \land P_{\mathrm{resource}} \land P_{\mathrm{tool}} \land P_{\mathrm{org}} \land P_{\mathrm{runtime}}

PdelegationP_{\mathrm{delegation}}, PresourceP_{\mathrm{resource}}, PtoolP_{\mathrm{tool}}, PorgP_{\mathrm{org}}, and PruntimeP_{\mathrm{runtime}} are the delegation, resource, tool, organization, and runtime policy predicates. Only when an event satisfies all of them should it enter the allowed space of this run.

This decomposition aligns with existing research directions. AC4A grounds agent access control in API resources and web resources, requiring applications to define resource hierarchies and compute permissions needed for successful access at runtime; this corresponds to AresourceA_{\mathrm{resource}} and AtoolA_{\mathrm{tool}} here.6 Authenticated Delegation and Authorized AI Agents focuses on how users delegate permissions to AI agents and translate natural-language permissions into auditable access-control configuration; this corresponds to Adelegated(τ)A_{\mathrm{delegated}}(\tau).7 Agentic JWT tries to bind an agent action to verifiable user intent and workflow step, which sits at the boundary between Adelegated(τ)A_{\mathrm{delegated}}(\tau) and AruntimeA_{\mathrm{runtime}}.8 MCP proxy research shows that tool access cannot be reliably limited by prompts alone, and that tool discovery and tool calls need architectural enforcement; this corresponds to AtoolA_{\mathrm{tool}} and AruntimeA_{\mathrm{runtime}}.9

So, in simplified notation, the single-step action set that should actually be opened for this run is:

Aallowed(C,τ)Aeff(C)Atask(τ)A_{\mathrm{allowed}}(C,\tau) \triangleq A_{\mathrm{eff}}(C) \cap A_{\mathrm{task}}(\tau) Pathallowed(C,τ)Lagent(C,τ)Aallowed(C,τ)Lreviewed(C,τ)\mathrm{Path}_{\mathrm{allowed}}(C,\tau) \triangleq L_{\mathrm{agent}}(C,\tau) \cap A_{\mathrm{allowed}}(C,\tau)^* \cap L_{\mathrm{reviewed}}(C,\tau)

Aallowed(C,τ)A_{\mathrm{allowed}}(C,\tau)^* denotes all finite sequences composed of actions allowed for this run. Lagent(C,τ)L_{\mathrm{agent}}(C,\tau) denotes paths the runtime may generate. Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau) denotes the reviewed path language valid for the current control subject and task; it may come from a design-time fixed flow, runtime policy verification, human approval, or data-flow checks. Only the intersection of all three denotes paths that the runtime may generate, whose local actions all fall inside the task slice, and whose full path is covered by a review mechanism.

A task-delegation overreach example is release-risk analysis. Suppose the user says, "Check the risk of this release and give me recommendations." The current agent runtime may be connected to the requirements platform, testing platform, CI system, and deployment system. So Aeff(C)A_{\mathrm{eff}}(C) may contain read_requirement, read_test_report, read_ci_status, and deploy_production. But the current task τ\tau only authorizes risk checking and recommendation generation. Atask(τ)A_{\mathrm{task}}(\tau) should contain the first three read actions and should not contain deploy_production. If the runtime triggers production deployment after generating the report, then even if the deployment API's single-step authorization passes, it has exceeded the task slice and must not enter Aallowed(C,τ)A_{\mathrm{allowed}}(C,\tau) or Pathallowed(C,τ)\mathrm{Path}_{\mathrm{allowed}}(C,\tau).

These formulas express four things. Aeff(C)A_{\mathrm{eff}}(C) is the total capability theoretically controllable by the agent runtime. Atask(τ)A_{\mathrm{task}}(\tau) is the function slice that should be allowed by the current task. Aallowed(C,τ)A_{\mathrm{allowed}}(C,\tau) is the action range that should actually be opened for this run. Lreviewed(C,τ)L_{\mathrm{reviewed}}(C,\tau) is the source of path-level safety assurance. Even if every aka_k in a path belongs to Aallowed(C,τ)A_{\mathrm{allowed}}(C,\tau), path safety still cannot be inferred from local action legality. The whole path must be reviewed; the data movement across domains must be considered; and the path must not break task boundaries or organizational policy. This is more precise than "many identities." The problem is not how many identities the system has, nor the number of permission items. The problem is whether the same control subject can place multiple permission domains into a runtime path that has not been reviewed as a whole.

Traditional systems are often close to: "one fixed business function ~= one program boundary ~= one process or service boundary ~= one identity boundary ~= one least-privilege set."

Agent systems are closer to: "one agent control boundary ~= one function scope ~= multiple previously isolated callable tools or permission domains ~= runtime decides how to compose them ~= composition paths require renewed review."

That is why the identity boundary becomes difficult: traditional systems usually use identity boundaries to represent function boundaries; agents gather execution power for multiple functions into the same runtime control subject, so identity boundaries no longer equal task boundaries.

Composition Risk

Permission aggregation itself is not the final problem. The final problem is: after multiple locally safe actions are placed inside the same composable runtime, they may form a cross-domain path that was never reviewed as a whole; the original safety guarantees of each permission domain do not automatically hold for that composition path.

A single permission decision can be written as:

Allow(identityk,operationk,resourcek)\mathrm{Allow}(\mathrm{identity}_k, \mathrm{operation}_k, \mathrm{resource}_k)

Traditional IAM is good at deciding whether this predicate holds. In an agent system, the whole path needs a different judgment:

Safe([call1,call2,,calln],task,data_flow,policy)\mathrm{Safe}([\mathrm{call}_1, \mathrm{call}_2, \ldots, \mathrm{call}_n], \mathrm{task}, \mathrm{data\_flow}, \mathrm{policy})

In other words, the system must not only ask whether each step is legal. It must also ask:

Do these legal steps, when composed, still satisfy the user task, organizational boundary, and data-flow constraints?

The core claim is: local safety is not closed under composition. A single action, single identity entry point, or single permission domain may look safe in isolation. That does not imply that these actions remain safe when the same control subject chains them into an unreviewed cross-domain path. Intuitively:

Safe(A(i1))Safe(A(i2))⇏Safe(A(i1)A(i2))\mathrm{Safe}(A(i_1)) \land \mathrm{Safe}(A(i_2)) \not\Rightarrow \mathrm{Safe}(A(i_1) \circ A(i_2))

This is only an intuition. \circ just means "chained together"; I am not defining a strict set operation over two action sets. In an agent system, the right-hand side usually should not judge two abstract permission sets in isolation, but whether they are placed by CruntimeC_{\mathrm{runtime}} into the same path:

Path[a1,a2,,an],akAeff(C)\mathrm{Path} \triangleq [a_1, a_2, \ldots, a_n], \quad a_k \in A_{\mathrm{eff}}(C)

If the output of a1a_1 can become the input of a2a_2, the composition risk has already exceeded a single-access authorization decision.

More rigorously, composition risk requires a cross-domain action sequence. Let d1,d2DCd_1,d_2 \in D_C be two permission domains controlled by control subject CC, with d1d2d_1 \neq d_2. Let A(d1)A(d_1) and A(d2)A(d_2) be the action sets in the two domains. LocalSafe(a)\mathrm{LocalSafe}(a) means action aa is safe under this permission domain, resource system, and single-step authorization. [a,b]Lreviewed(C,τ)[a,b] \notin L_{\mathrm{reviewed}}(C,\tau) means the full composition path is not covered by the design-time or runtime review mechanism valid for the current control subject and task. GlobalSafe([a,b])\mathrm{GlobalSafe}([a,b]) means the whole path satisfies task delegation, organizational boundaries, and cross-domain or cross-system data-flow policies. The risk condition can be written as:

UnsafeComposition(C,τ)d1DC,d2DC, d1d2, aA(d1),bA(d2):LocalSafe(a)LocalSafe(b)[a,b]Lagent(C,τ)[a,b]Lreviewed(C,τ)¬GlobalSafe([a,b])\mathrm{UnsafeComposition}(C,\tau) \triangleq \exists d_1 \in D_C,\exists d_2 \in D_C,\ d_1 \neq d_2,\ \exists a \in A(d_1), \exists b \in A(d_2): \mathrm{LocalSafe}(a) \land \mathrm{LocalSafe}(b) \land [a,b] \in L_{\mathrm{agent}}(C,\tau) \land [a,b] \notin L_{\mathrm{reviewed}}(C,\tau) \land \neg \mathrm{GlobalSafe}([a,b])

This shows that the problem is not the presence of multiple actions in Aeff(C)A_{\mathrm{eff}}(C), nor that Aeff(C)>1|A_{\mathrm{eff}}(C)| > 1 is dangerous by itself. The problem is the existence of a runtime-generated cross-domain path where every local action passes its own authorization judgment, the full path is not covered by the original engineering review, and the path violates task, separation-of-duties, or data-flow constraints.

There are two layers to distinguish. [a,b]Lreviewed(C,τ)[a,b] \notin L_{\mathrm{reviewed}}(C,\tau) only says we cannot infer the safety of the composition path from the original system safety process. That is a governance gap. A real security incident requires this unreviewed path to also violate GlobalSafe\mathrm{GlobalSafe}. The new IAM model has to handle exactly this gap: bring cross-domain paths under review, constraint, or approval before execution, rather than waiting for each resource server to complete local authorization and then stitching logs together afterward.

Suppose an agent has two permissions that each look reasonable:

read:contracts
send:email

read:contracts may be used for contract summarization, risk analysis, and clause retrieval. send:email may be used to notify colleagues, send meeting notes, or reply to customers. Each permission may be approved on its own. But the composition path may become:

read contract -> summarize sensitive clauses -> send email to external counsel

More formally:

send_external_email(read_contract())exfiltrate_contract\mathrm{send\_external\_email}(\mathrm{read\_contract}(\cdot)) \Rightarrow \mathrm{exfiltrate\_contract}

Traditional IAM sees:

Single judgment Result
Can this identity read the contract? Yes
Can this identity send email? Yes
Is the token valid? Yes
Are the email API parameters valid? Yes
Is the recipient a valid address? Yes

But the real risk is at the composition layer: the user may have authorized only "summarize contract risk", not "send contract content to an external person." The contract system knows the contract was read. The email system knows an email was sent. Neither single resource server necessarily knows that the two steps formed a cross-system data movement chain in the same agent run.

Using the earlier existential condition, aa is reading the contract and bb is sending the external email. aA(dcontracts)a \in A(d_{\mathrm{contracts}}) and is locally legal inside the contract system. bA(demail)b \in A(d_{\mathrm{email}}) and is locally legal inside the email system. The danger comes from [a,b]Lagent(C,τ)[a,b] \in L_{\mathrm{agent}}(C,\tau), while this path was not reviewed as "read contract content and send it to external counsel." Contract content flows from the contract permission domain into the email permission domain and is sent to an external destination not authorized by the current task. The two permissions existing separately are not necessarily dangerous. Runtime path generation is not necessarily dangerous. The danger appears when the runtime composes them into an unreviewed cross-domain data-flow path that violates global policy.

This example is not speculative. Research on GPT Actions data practices has grounded similar concerns in a real ecosystem. Researchers analyzed natural-language specifications of GPT Actions and found that actions collect 145 data types across 24 categories, including sensitive information in some cases. They also found insufficient privacy-policy disclosure: only 5.8% of actions clearly disclosed data-collection practices.10 This kind of research is not saying "some token is invalid." It shows that after external actions are connected to an LLM app ecosystem, which tools collect what data, how data flows across tools, and whether that matches user expectations have already exceeded what traditional single API authorization can express.

Composition risk is not only data egress. Another example is a refund process: the customer-support system allows creating a refund request, the finance system allows approving a refund, and the email system allows notifying a customer. All three single-step actions may have legitimate uses. But if the same agent runtime completes, in one task:

create refund request -> automatically approve the same refund -> notify customer

then the issue becomes a collapse of separation of duties. In a traditional process, creating a refund request and approving the refund may belong to different roles, different approval nodes, or different system control points. Once the agent runtime places those actions into the same unreviewed path, the risk is not in "refund request" or "customer notification" alone. It is that the same control subject completed a decision chain that should have been separated.

More generally, composition risk has three types:

Risk type Traditional IAM single judgment New problem in an agent run
Data movement System A permits read, system B permits write Is A's data allowed to be written into B?
Separation-of-duties collapse Each permission is assigned to a legal identity or service Agent runtime puts responsibilities that used to be separated under one control subject
User-delegation overreach App has scope, token is valid Does this task authorize this tool chain and destination?

The point is not "agents are untrusted and traditional programs are trusted." A more accurate statement is: the capability space of traditional programs is usually compressed by reviewed path languages, code review, and least privilege; agents, in order to execute general tasks, place multiple capabilities that used to be individually constrained by reviewed paths into one composable runtime, making unreviewed cross-domain composition paths a new governance object.

New Identity Modeling Objects

If the problem is permission composition, the new object cannot be merely "the agent identity." Traditional IAM's basic judgment still exists:

subjectactionresource\mathrm{subject} \rightarrow \mathrm{action} \rightarrow \mathrm{resource}

But agent systems also need to express:

taskruntimepathtoolidentityoperationresourcedata_flow\mathrm{task} \rightarrow \mathrm{runtime} \rightarrow \mathrm{path} \rightarrow \mathrm{tool} \rightarrow \mathrm{identity} \rightarrow \mathrm{operation} \rightarrow \mathrm{resource} \rightarrow \mathrm{data\_flow}

Using the same task, an allowed agent run can be recorded as the following event trace:

Field Example value
run R-17
task Summarize contract C-42 and send it to legal@corp.com
event 1 Use user delegated token to read contract/C-42
event 2 Use email identity entry point to send body summary to legal@corp.com
data flow contract/C-42 -> summary -> internal legal recipient
decision allow
policy basis Recipient is in internal legal group; attachments forbidden; body may contain only summary

The point of this record is not to write one more log line for every API call. It is to put task, identity entry point, tool, resource, parameters, data provenance, and policy judgment into the same trace. Only then can authorization and audit systems answer "why was this email allowed?" rather than only seeing separately that "a contract was read" and "an email was sent."

These objects follow naturally from the formalization above:

Modeling object Reason to model it
Task Scope says what an app can do, not what this user delegation allows in this run
Runtime Multiple identity entry points are selected and composed at runtime
Path / Trace Risk appears in an event trace with parameters, provenance, and external effects, not in one API call
Tool A tool packages permission, input, output, and side effects
Control subject We need to know which runtime actually controls multiple permission domains, not only the local identities inside each resource system
Identity entry An agent run may use user identity, application identity, connector credential, service account, and other entry points; identity count is not the root cause
Reviewed path We need to know whether the composition path is covered by a design-time process, runtime policy, approval, or data-flow check
Permission composition A single legal permission does not make an unreviewed composition path safe
Data flow We need to know which permission domain or system data came from, and which domain, system, or external destination it went to
Run audit After the fact, we need to reconstruct task, delegation chain, tools, identities, parameters, data provenance, policy judgments, and external effects

So a stricter definition should not start by declaring "what Agent IAM is." It should first define the problem:

The foundational problem of agent identity  multiple permission domains that were previously isolated+control over those domains by the same runtime control subject+a multi-tool set+cross-domain composition paths+a governance gap outside the reviewed path language+cross-domain or cross-system data flow\begin{aligned} \text{The foundational problem of agent identity} \triangleq\;& \text{multiple permission domains that were previously isolated} \\ &+ \text{control over those domains by the same runtime control subject} \\ &+ \text{a multi-tool set} \\ &+ \text{cross-domain composition paths} \\ &+ \text{a governance gap outside the reviewed path language} \\ &+ \text{cross-domain or cross-system data flow} \end{aligned}

If the corresponding governance extension is tentatively called Agent IAM, it can be defined as:

Agent IAM  traditional IAM+governance over task, control subject, runtime path, reviewed path, tool,identity entry, permission composition, and data flow inside agent runs\begin{aligned} \text{Agent IAM} \triangleq\;& \text{traditional IAM} \\ &+ \text{governance over task, control subject, runtime path, reviewed path, tool,} \\ &\quad \text{identity entry, permission composition, and data flow inside agent runs} \end{aligned}

This definition preserves traditional IAM. It does not replace user identity, service accounts, OAuth, RBAC, or ABAC. It adds the part traditional IAM usually did not have to model explicitly when path sets were reviewed ahead of time by programs and processes, but which agent systems must model explicitly.

Conclusion

The foundational problem of agent identity is not as simple as "agents need accounts." Traditional IAM can already create identities for programs, issue tokens, assign scopes, and produce audit logs. The real new problem comes from a change in the object of safety assurance: traditional automation is usually secured by a reviewed path language jointly defined by fixed business functions, constrained path sets, code review, and least privilege; agent systems place multiple permission domains, previously constrained by those path languages, under the same composable runtime control subject.

Runtime path generation alone is not the full problem. The full problem is that, to produce real business effects, an agent system connects multiple permission domains, tool capabilities, or external effects that used to be separated. These boundaries bring different permission domains and identity entry points. Those entry points are dynamically selected inside the same runtime, and may form cross-domain composition paths that were not reviewed as a whole. Multiple individually legal accesses may, when composed into a specific action sequence, break user delegation, separation-of-duties, and data-flow boundaries.

So the final conclusion of this article is: from a systems perspective, the foundational problem of agent identity is cross-domain composition path governance by the same runtime control subject over multiple previously isolated permission domains. The new IAM extension has to fill the layer that asks whether the composition path was reviewed, whether it matches the current task, and whether this data flow is allowed. It should not reinvent single-step authentication and authorization. Only after this problem is formalized can discussions of Agent IAM, agent discovery, tool authorization, MCP gateways, runtime approval, and audit trails have a stable starting point.

References

Footnotes

  1. Microsoft Learn, "Data, Privacy, and Security for Microsoft 365 Copilot". https://learn.microsoft.com/en-us/copilot/microsoft-365/microsoft-365-copilot-privacy

  2. Microsoft Learn, "Security filters for trimming results in Azure AI Search". https://learn.microsoft.com/en-us/azure/search/search-security-trimming-for-azure-search

  3. Microsoft Learn, "Add tools to custom agents". https://learn.microsoft.com/en-us/microsoft-copilot-studio/add-tools-custom-agent

  4. OpenAI Help Center, "Creating and editing GPTs", updated June 2026. https://help.openai.com/en/articles/8554397-creating-a-gpt

  5. OpenAI Developers, "GPT Actions". https://developers.openai.com/api/docs/actions/introduction

  6. Reshabh K Sharma, Dan Grossman, "AC4A: Access Control for Agents", arXiv:2603.20933, 2026. https://arxiv.org/abs/2603.20933

  7. Tobin South, Samuele Marro, Thomas Hardjono, Robert Mahari, Cedric Deslandes Whitney, Dazza Greenwood, Alan Chan, Alex Pentland, "Authenticated Delegation and Authorized AI Agents", arXiv:2501.09674, 2025. https://arxiv.org/abs/2501.09674

  8. Abhishek Goswami, "Agentic JWT: A Secure Delegation Protocol for Autonomous AI Agents", arXiv:2509.13597, 2025. https://arxiv.org/abs/2509.13597

  9. Rohith Uppala, "Prompts Don't Protect: Architectural Enforcement via MCP Proxy for LLM Tool Access Control", arXiv:2605.18414, 2026. https://arxiv.org/abs/2605.18414

  10. Yuhao Wu, Evin Jaff, Ke Yang, Ning Zhang, Umar Iqbal, "An In-Depth Investigation of Data Collection in LLM App Ecosystems", arXiv:2408.13247, revised 2025. https://arxiv.org/abs/2408.13247