Agent Identity Governance
Microsoft Entra Agent ID · Governance

A governance framework for agent identities in Microsoft Entra.

Agent identities authenticate as service principals, hold OAuth scopes, and act autonomously across the tenant. This is a reference architecture for enforcing owner accountability, declarative permission scoping, and lifecycle deprovisioning on every agent, implemented through the Microsoft Graph API with Conditional Access as the enforcement backstop.

Multiple
provisioning channels emitting agent identities, with more expected
1
attribute-driven CA gate every agent must clear
2
detection paths: event-driven plus authoritative reconciliation
01 · The problem

Agent identities are proliferating outside any governance perimeter.

An agent identity is a first-class security principal in the tenant. It inherits from servicePrincipal, carries delegated and application permissions, and acquires tokens. When one is provisioned without an owner relationship, without declared scopes, and without a lifecycle trigger, it becomes an unmanaged non-human identity with standing access and no control plane.

No owner accountability

Disabling the creating user's account has no cascading effect on the agents they own. Without an explicit owner-to-principal link and a leaver trigger, orphaned agents retain active credentials indefinitely.

Undeclared permission scope

Agents accrue appRoleAssignments and OAuth grants with no baseline to audit against. There is no declared scope to certify during access reviews and no authoritative state to revoke against.

No lifecycle enforcement

The platform performs no automatic disablement on owner departure. Absent custom automation against the Graph API, an agent's accountEnabled state never changes when its accountable human leaves.

02 · Today

Provisioning is fragmented across multiple channels.

Copilot Studio, Azure AI Foundry, the Graph API, and custom code all emit agent identities today, with no shared convention, and additional provisioning surfaces are likely as the platform evolves. Owner and sponsor relationships can be assigned, but enforcement is conditional at best, and custom security attributes, tags, and approval state are inconsistent across every path.

Current creation flow: inconsistent across origins
Copilot Studio
auto-provisioned at publish
Azure AI Foundry
agent project identity
Graph API / SDK
owner + sponsor via API
Custom code
MSAL client credential
agentIdentity created in Entra
servicePrincipalType = ServiceIdentity · active immediately
Sponsor conditional, owner optional
delegated-flow default only
No CSA / tags
no enforcement or reporting surface
No CA enforcement gate
policy can't distinguish approved principals

Sponsor is auto-assigned to the calling user only in delegated (user-context) creation, only when no sponsor is specified, and not for Agent ID admin-role callers. App-only flows must set it explicitly. The outcome is an inconsistent governance posture, not a deliberate one.

Native administrative surface in the Entra admin center

Every agent identity, regardless of provisioning channel, surfaces in the Entra admin center under Agent ID and Enterprise applications. Administrators can enumerate principals, inspect native properties (display name, blueprint ID, owners, sponsors, sign-in activity), and disable individual objects. The surface is sufficient for visibility and reactive containment but does not provide the governance primitives this architecture introduces: no native intake or approval workflow, no enforced ownership or metadata contract at creation, no policy-driven denial of unapproved principals, no scheduled certification or owner-departure cascade, and no aggregated view across blueprint, classification, and lifecycle state. The architecture below adds those capabilities as a control plane on top of the native surface.

03 · The approach

A single metadata model with two enforcement tiers.

Each agent carries a structured metadata set split between enforcement-grade custom security attributes and auditable tags. A Conditional Access policy evaluates the approval attribute and blocks token issuance for any principal not explicitly approved, independent of the provisioning channel.

Custom Security Attributes

Typed, schema-validated, and queryable. Only string-typed CSA can be referenced by a CA policy filter, so all enforcement-targetable fields, including ownership, approval state, classification, and department scope, are modeled here.

Tags

A self-sufficient label set that forms an auditable record for inventory, chargeback, and compliance dashboards, readable without the elevated CSA role. Tags are not CA-targetable, so they carry audit-only attributes and mirrored copies of enforcement fields for traceability.

Conditional Access gate

The enforcement backstop. A policy excludes only principals carrying approvalStatus: Approved from a block rule, so any agent lacking the attribute is denied token issuance until governance is satisfied.

The load-bearing attribute

Every agent is provisioned with approvalStatus: New and is denied by policy from inception. A security review is the only transition that sets Approved. This converts "governable in principle" into "governed by default," uniformly, across all provisioning channels.

Alignment with governance standards

The model maps to recognized non-human identity controls: owner accountability and least-privilege scoping satisfy the identity-governance expectations in NIST SP 800-53 (AC-2, AC-6) and ISO/IEC 27001 Annex A access-control objectives, while periodic certification and automated deprovisioning address the lifecycle requirements increasingly called out for machine and agent identities. Conditional Access enforcement provides the Zero Trust verification layer Microsoft's own guidance recommends for agent principals.

04 · Proposed schema

The metadata contract on every agent.

Metadata is distributed across three locations on the agentIdentity object. Native fields are platform-managed; tags carry auditable labels; custom security attributes form the enforcement-grade store, grouped by function.

Agent identity: populated example
agentIdentity
Finance-Invoice-Processor-v1
Native fields
  • servicePrincipalType ServiceIdentity
  • accountEnabled true
  • agentIdentityBlueprintId BPW-01
  • createdDateTime 2026-06-01
Relationships
  • owner alice@contoso.com
  • sponsor bob@contoso.com
Tags · reporting
  • team:finance-automation
  • cost-center:FIN-001
  • env:production
  • purpose:files-invoices
  • status:Approved
Custom Security Attributes · AgentGov
Ownership
  • ownerObjectId
  • ownerUPN
  • sponsorUPN
Access enforcement
  • approvalStatus
  • blueprintName
  • approvedForDepts
  • dataClassification
  • environment
Lifecycle / audit
  • maxPermissionTier
  • provisionedBy
  • serviceNowRITM
  • reviewDueDate
Why blueprintName is a CSA, not just a tag

CA app-filter rules can target a class of agents by a string-typed custom security attribute. Modeling blueprint name as a CSA enables a single durable policy expression across an entire blueprint class, complementing native blueprint-ID targeting rather than enumerating object IDs.

Why agentPurpose is a tag, not a CSA

Free-text purpose is never CA-targetable, so it adds no enforcement value as an attribute. As a tag it remains accessible to reporting pipelines and review notifications without provisioning the elevated CSA assignment role.

05 · Governance

Continuous detection and remediation.

Most agents originate in Azure AI Foundry and Copilot Studio, which provision identities directly without passing through a central intake. Governance therefore runs as a detection-and-remediation loop: every agent is discovered, evaluated against the metadata contract, and held at the CA gate until it is complete and approved.

Approval state: the gate every agent passes through
New InReview Approved Suspended

New and InReview are denied; Approved is the only token-issuing state. Owner departure or a failed certification transitions the principal to Suspended, also denied. The CA policy expression is static; only the attribute value transitions.

Governance flow: detection and remediation
Agent identity created
any channel
Path A · event-driven (low latency)
Audit: Add service principal
non-specific directory event
Log Analytics scheduled alert
confirms ServiceIdentity type · ~15 min
Path B · reconciliation (authoritative)
GET agentIdentity collection
hourly + daily sweep
Evaluate tags + CSA
authoritative backstop
Metadata completeness check
owner + approvalStatus + CSA present?
Raise ServiceNow RITM
gap detail + severity classification
Notify owner / creator
resolved from native principal data
Requestor completes RITM
supplies owner, sponsor, blueprint, classification
Automation reads RITM fields
PATCH tags + CSA on the agent identity
Security review → approvalStatus: Approved
CA exclusion permits token issuance
Backstop · always enforced

CA-AGENT-001 denies any principal not carrying approvalStatus: Approved throughout the lifecycle, so the agent remains non-functional during the window before either detection path completes its evaluation.

Sample Graph calls behind each step
# Path B: enumerate all agent identities (authoritative sweep)
GET /servicePrincipals/microsoft.graph.agentIdentity
    ?$select=id,displayName,accountEnabled,createdDateTime,
             agentIdentityBlueprintId,tags,customSecurityAttributes
    &$orderby=createdDateTime desc &$top=100

# Sample response: each item is typed as agentIdentity, a subtype of servicePrincipal
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals",
  "value": [
    {
      "@odata.type": "#microsoft.graph.agentIdentity",
      "id": "8a2f9c41-1d4e-4b87-9a3c-7e9f2d11c91d",
      "displayName": "Finance-Invoice-Processor-v1",
      "accountEnabled": true,
      "createdDateTime": "2026-06-01T09:14:22Z",
      "servicePrincipalType": "ServiceIdentity",
      "agentIdentityBlueprintId": "a1b2c3d4-BPW01",
      "tags": [ "env:production", "team:finance-automation",
                 "blueprint:files-readwrite", "status:Approved" ],
      "customSecurityAttributes": {
        "AgentGov": {
          "approvalStatus": "Approved",
          "ownerObjectId": "7c4f...e21a",
          "dataClassification": "Confidential"
        }
      }
    }
  ]
}

# Completeness check: read CSA + owners for one agent
GET /servicePrincipals/{id}?$select=customSecurityAttributes
GET /servicePrincipals/{id}/microsoft.graph.agentIdentity/owners

# Automation step: PATCH tags + CSA from RITM submission
PATCH /servicePrincipals/{id}/microsoft.graph.agentIdentity
{
  "tags": [ "env:production", "team:finance-automation",
             "blueprint:files-readwrite", "status:New" ],
  "customSecurityAttributes": {
    "AgentGov": {
      "@odata.type": "#microsoft.graph.CustomSecurityAttributeValue",
      "approvalStatus": "New",
      "ownerObjectId": "{ownerObjectIdFromRITM}",
      "sponsorUPN": "{sponsorUPNFromRITM}",
      "blueprintName": "{blueprintFromRITM}",
      "dataClassification": "{classificationFromRITM}"
    }
  }
}

# Backstop: deny token issuance until approved (Conditional Access)
POST /identity/conditionalAccess/policies
{
  "displayName": "CA-AGENT-001: Block unapproved agent identities",
  "state": "enabled",
  "grantControls": { "operator": "OR", "builtInControls": ["block"] }
}

The reconciliation sweep is the authoritative source because the dedicated microsoft.graph.agentIdentity endpoint returns only agent identities and includes the blueprint ID and custom security attributes in a single paged response, unlike the generic audit event, which does not reliably carry agent-specific fields at creation time.

06 · Lifecycle management

Owner and sponsor departures cascade automatically.

The accountability chain only holds if it survives joiner-mover-leaver events. A scheduled job evaluates the directory state of each agent's owner and sponsor, escalates when one role is unresolvable, and suspends the principal when both are. Conditional Access remains the enforcement backstop throughout.

One principal unavailable: notify and remediate

If the owner or sponsor is disabled, soft-deleted, or no longer a member of the directory, the lifecycle job notifies the remaining principal with the agent identifier, the missing role, and a link to the ServiceNow RITM template for ownership update. The agent continues to operate so business workloads are not interrupted while the gap is being closed.

Both unavailable: suspend and disable

If both owner and sponsor are unresolvable, no accountable human remains. The job stamps approvalStatus: Suspended on the agent (CA-AGENT-001 then denies all tokens) and PATCHes accountEnabled: false on the principal. A P1 ServiceNow incident is raised to the blueprint owner team for review or formal decommission.

Lifecycle evaluation: per-agent state machine
Scheduled lifecycle sweep
daily, all agent identities
Resolve owner + sponsor in directory
check accountEnabled + soft-delete state
Both resolvable
no action · log healthy
One unresolvable
notify remaining principal with RITM link
Both unresolvable
PATCH approvalStatus: Suspended + accountEnabled: false · raise P1 RITM
Backstop · CA enforces

Once approvalStatus transitions off Approved, CA-AGENT-001 denies token issuance immediately, even while accountEnabled changes are still propagating. The CSA value is the authoritative enforcement signal.

Sample Graph calls for lifecycle remediation
# Resolve owner state: check if user exists and is enabled
GET /users/{ownerObjectId}?$select=id,accountEnabled,userPrincipalName
# A 404 response (or accountEnabled: false) indicates the owner is unresolvable

# Both principals unavailable: suspend the agent and disable the SP
PATCH /servicePrincipals/{id}/microsoft.graph.agentIdentity
{
  "accountEnabled": false,
  "customSecurityAttributes": {
    "AgentGov": {
      "@odata.type": "#microsoft.graph.CustomSecurityAttributeValue",
      "approvalStatus": "Suspended",
      "suspendedReason": "OwnerSponsorBothUnresolvable",
      "suspendedDate": "2026-06-13"
    }
  }
}
07 · Conditional Access policy

How the approvalStatus gate is evaluated.

Microsoft Entra Conditional Access for Agent ID treats agent identities as first-class principals and evaluates their token-acquisition flows against tenant policy. Two scenarios apply directly to this architecture: restrict token issuance to approved agents only, and deny token issuance to agents flagged high-risk by Microsoft Entra ID Protection. Both target string-typed custom security attributes on the agent identity.

CA-AGENT-001: evaluate approvalStatus on token request
Request access
Agent Identity A
approvalStatus: Approved
blueprintName: files-readwrite
origin: Copilot Studio
Agent Identity B
approvalStatus: New
blueprintName: mail-send
origin: Copilot Studio
Agent Identity C
approvalStatus: (not set)
origin: Azure AI Foundry
Conditional access evaluation
approvalStatus = "Approved"
Grant access
Block access

Token acquisition triggers CA evaluation against the agent's AgentGov.approvalStatus CSA. Agent A matches the exclusion criterion and is granted access. Agents B and C do not (New, or attribute absent) and are denied, irrespective of provisioning channel. This implements the Scenario 1 pattern documented in Microsoft Learn for CSA-driven agent targeting: the rule is expressed as exclusion-from-block, so any principal lacking the attribute fails closed.

CA-AGENT-002: scope agent access by department
Request access to HR resource
Agent Identity A
approvedForDepts: [HR, Finance]
dataClassification: Confidential
origin: Graph API
Agent Identity B
approvedForDepts: [Marketing]
dataClassification: Internal
origin: Copilot Studio
Agent Identity C
approvedForDepts: (not set)
origin: Azure AI Foundry
Conditional access evaluation
approvedForDepts Contains "HR"
(resource.department = HR)
Grant access
Block access

The target resource carries ResourceAccess.department: HR. The policy grants only agents whose approvedForDepts CSA contains the resource's department value. Agent A is scoped to HR and Finance and is granted; Agent B is scoped to Marketing only and is denied; Agent C has no department scope and fails closed.

CA-AGENT-003: block agents flagged high-risk
Request access
Agent Identity A
Agent risk: Low
approvalStatus: Approved
origin: Graph API
Agent Identity B
Agent risk: Medium
approvalStatus: Approved
origin: Copilot Studio
Agent Identity C
Agent risk: High
approvalStatus: Approved
origin: Azure AI Foundry
Conditional access evaluation
Agent risk < "High"
(Entra ID Protection signal)
Grant access
Block access

The risk signal is sourced from Microsoft Entra ID Protection, which evaluates behavioral and contextual anomalies for each agent identity. Agents A and B are at Low and Medium risk respectively and are granted. Agent C is flagged High and is denied, even though its approvalStatus is Approved. Risk-based and attribute-based policies compose additively: the principal must clear every policy on the token-acquisition path.

Policy composition on the token-acquisition path

Every applicable policy is evaluated for each agent token request. CA-AGENT-001 enforces approval state; CA-AGENT-002 enforces resource-department scope; CA-AGENT-003 enforces risk-based denial. The principal must clear all three; failure of any single policy results in token denial. Each policy reads a distinct CSA group or Microsoft Entra ID Protection signal, so the controls are independent and additive.

Investigation via sign-in logs

Every CA evaluation for an agent identity is captured in the Microsoft Entra sign-in logs. Filter Service principal sign-ins on agentType = agent identity to retrieve the policies applied, the inclusion or exclusion clauses evaluated, and the CSA values read at decision time. This is the authoritative diagnostic source when an approved agent is unexpectedly denied or an unapproved agent is observed acquiring tokens.

08 · Placement matrix

Where each metadata field lives.

The placement rule is deterministic: enforcement-targetable fields are modeled as custom security attributes; audit-only fields as tags; fields serving both are mirrored. Only string-typed CSA are CA-targetable.

AttributePlacementRationale
approvalStatusCSA TagCA policy evaluates the CSA; the tag mirror feeds dashboards without the CSA read role.
blueprintNameCSA · Tag · NativeCA-targetable as a string CSA, reportable as a tag, and present as the native blueprint ID.
dataClassificationCSA TagScopes CA policy by sensitivity tier and feeds classification reporting.
approvedForDeptsCSADrives department-scoped CA; multi-value, enforcement-only.
ownerObjectId / ownerUPNCSA TagLeaver automation resolves the object ID; reporting reads the tag mirror.
agentPurposeTagFree text is not CA-targetable; reporting and review notifications only.
serviceNowRITMCSA TagBinds the principal to its originating request record for audit traceability.
costCenter / teamTagChargeback and ownership reporting; no enforcement dependency.
09 · References

Source documentation.

Primary Microsoft Learn references for the agent identity resource model, administrative relationships, Conditional Access targeting, and the Graph endpoints used throughout this architecture.

Microsoft Entra Agent ID is in preview at the time of writing; resource shapes and endpoint paths may change before general availability. Verify against the live documentation before implementation.