Type to search 66 articles.

    Practical engineering guidance

    Securing enterprise AI agents: a hands-on Microsoft implementation guide

    A practical guide to governing AI agents with Entra Agent ID, Conditional Access, Defender and Purview, including PowerShell, Graph requests and validation.

    • AI security
    • Microsoft Entra ID
    • Microsoft Defender

    What this guide builds

    AI agents can read data, call tools and take actions at machine speed. A production design needs an accountable identity, narrowly scoped access, a controlled execution path, data protection, runtime monitoring and a tested way to stop the agent.

    This worked example creates an autonomous reporting agent that reads approved data and produces a report. It does not receive permission to modify users, applications or directory roles. You will build:

    • an inventory and approval record;
    • a Microsoft Entra agent identity blueprint with an owner and sponsor;
    • a dedicated child agent identity;
    • credentialless authentication from an Azure managed identity;
    • a Conditional Access boundary deployed first in report-only mode;
    • Microsoft Defender discovery and monitoring; and
    • validation, containment and recovery procedures.

    Microsoft Entra Agent ID, Conditional Access for agents and some Defender for Agent 365 features may be preview or licence-dependent. Test in a non-production tenant and verify availability before production use.

    Architecture and trust boundaries

    Use a separate identity for each deployed agent instance. The identity blueprint defines common configuration; each agent identity becomes the auditable principal requesting access.

    The request path should be:

    1. The workload authenticates from an approved Azure environment.
    2. Microsoft Entra issues a token for the agent identity.
    3. Conditional Access evaluates the agent, target resource and risk.
    4. The target API enforces its own permissions.
    5. Defender and resource audit logs record the action.
    6. High-impact tools require approval outside the model response.

    Keep read, propose and execute as separate capabilities. A reporting agent can read and propose. A separate workflow should execute privileged changes after approval.

    Prerequisites

    Prepare a test tenant and confirm:

    • PowerShell 7 and Microsoft Graph PowerShell;
    • Agent ID Administrator or Agent ID Developer for blueprint work;
    • Conditional Access Administrator for access policies;
    • Security Administrator for Defender configuration;
    • an Azure workload with a managed identity; and
    • the licences required for the features you will test.

    Install the Graph modules:

    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
    Install-Module Microsoft.Graph.Authentication -Scope CurrentUser
    Install-Module Microsoft.Graph.Applications -Scope CurrentUser
    Install-Module Microsoft.Graph.Users -Scope CurrentUser
    
    Get-InstalledModule Microsoft.Graph* |
      Select-Object Name, Version |
      Sort-Object Name

    Do not paste production secrets into a console transcript, repository or AI prompt. The production path below uses managed identity federation.

    Step 1: create the governance record

    Create the record before the identity. A repository-backed YAML file makes ownership reviewable:

    agentId: finance-reporting-agent-prod
    purpose: Read approved finance data and prepare a daily summary
    businessOwner: finance-operations
    technicalOwner: cloud-platform
    sponsor: named-user-or-supported-group
    environment: production
    dataClassification: confidential
    allowedDataSources:
      - approved-reporting-api
    allowedActions: [read, summarise]
    blockedActions: [update-records, send-external-email, change-permissions]
    humanApprovalRequired: [publish-report]
    reviewFrequencyDays: 90
    expiryDate: 2027-09-19

    The owner maintains the service. The sponsor remains accountable for its business purpose. Reject identities with no sponsor, no expiry or an undefined data boundary.

    Step 2: connect to Microsoft Graph

    Replace the example values before running any command:

    $TenantId = "00000000-0000-0000-0000-000000000000"
    $BlueprintName = "Finance Reporting Agent Blueprint"
    $AgentName = "Finance Reporting Agent - Production"
    
    Connect-MgGraph -TenantId $TenantId -Scopes @(
      "AgentIdentityBlueprint.Create"
      "AgentIdentityBlueprint.AddRemoveCreds.All"
      "AgentIdentityBlueprint.UpdateAuthProperties.All"
      "AgentIdentityBlueprintPrincipal.Create"
      "AgentIdentity.Create.All"
      "User.Read"
    )
    
    Get-MgContext | Select-Object TenantId, Account, Scopes

    Review the consent screen. In production, split creation, credential management and approval between operators rather than granting one administrator every scope permanently.

    Step 3: create the agent identity blueprint

    The sponsor is mandatory. This lab uses the signed-in administrator as initial owner and sponsor; assign the accountable production sponsor afterward.

    $Context = Get-MgContext
    $CurrentUser = Get-MgUser -UserId $Context.Account
    
    $BlueprintBody = @{
      "@odata.type" = "Microsoft.Graph.AgentIdentityBlueprint"
      displayName = $BlueprintName
      "sponsors@odata.bind" = @(
        "https://graph.microsoft.com/v1.0/users/$($CurrentUser.Id)"
      )
      "owners@odata.bind" = @(
        "https://graph.microsoft.com/v1.0/users/$($CurrentUser.Id)"
      )
    } | ConvertTo-Json -Depth 5
    
    $Blueprint = Invoke-MgGraphRequest `
      -Method POST `
      -Uri "https://graph.microsoft.com/v1.0/applications/microsoft.graph.agentIdentityBlueprint" `
      -Headers @{ "OData-Version" = "4.0" } `
      -Body $BlueprintBody `
      -ContentType "application/json"
    
    $Blueprint | Select-Object id, appId, displayName
    $BlueprintObjectId = $Blueprint.id
    $BlueprintAppId = $Blueprint.appId

    Do not use New-MgApplication, New-AzADApplication or az ad app create. They create a standard application, not an Agent ID object with agent sponsorship, lifecycle and audit behaviour.

    Create the blueprint principal:

    $PrincipalBody = @{ appId = $BlueprintAppId } | ConvertTo-Json
    
    $BlueprintPrincipal = Invoke-MgGraphRequest `
      -Method POST `
      -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/microsoft.graph.agentIdentityBlueprintPrincipal" `
      -Headers @{ "OData-Version" = "4.0" } `
      -Body $PrincipalBody `
      -ContentType "application/json"
    
    $BlueprintPrincipal | Select-Object id, appId, displayName, accountEnabled

    The application object ID, application/client ID and principal object ID are different. Label each one in the deployment record.

    Step 4: configure managed identity federation

    For an agent on Azure App Service, Functions, Container Apps or a VM, prefer managed identity over a secret. Obtain the managed identity’s principal object ID:

    $ManagedIdentityPrincipalId = "11111111-1111-1111-1111-111111111111"
    
    $FederatedCredential = @{
      Name = "finance-reporting-agent-azure-mi"
      Issuer = "https://login.microsoftonline.com/$TenantId/v2.0"
      Subject = $ManagedIdentityPrincipalId
      Audiences = @("api://AzureADTokenExchange")
    }
    
    New-MgApplicationFederatedIdentityCredential `
      -ApplicationId $BlueprintObjectId `
      -BodyParameter $FederatedCredential
    
    Get-MgApplicationFederatedIdentityCredential `
      -ApplicationId $BlueprintObjectId |
      Select-Object Id, Name, Issuer, Subject, Audiences

    Use a certificate where managed identity is unavailable. Use a client secret only for short-lived development, keep its lifetime short and store it in a managed vault.

    Step 5: create the child agent identity

    The child is the runtime principal. The agentIdentityBlueprintId value is the blueprint app ID.

    $AgentBody = @{
      displayName = $AgentName
      agentIdentityBlueprintId = $BlueprintAppId
      "sponsors@odata.bind" = @(
        "https://graph.microsoft.com/v1.0/users/$($CurrentUser.Id)"
      )
    } | ConvertTo-Json -Depth 5
    
    $AgentIdentity = Invoke-MgGraphRequest `
      -Method POST `
      -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/microsoft.graph.agentIdentity" `
      -Headers @{ "OData-Version" = "4.0" } `
      -Body $AgentBody `
      -ContentType "application/json"
    
    $AgentIdentity | Select-Object id, displayName, servicePrincipalType, agentIdentityBlueprintId
    $AgentObjectId = $AgentIdentity.id

    Validate the object:

    $AgentCheck = Invoke-MgGraphRequest `
      -Method GET `
      -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$AgentObjectId"
    
    $AgentCheck | Select-Object id, displayName, servicePrincipalType, accountEnabled

    Also verify it in Microsoft Entra admin center > Entra ID > Agents > Agent identities.

    Step 6: grant the minimum permission

    Start with no resource permission. Map every required API operation to the narrowest delegated scope, application role or resource-specific role. Microsoft blocks several high-risk permissions for agent identities, but that boundary does not replace your least-privilege review.

    A blueprint can define which resource apps have inheritable permissions. This defines what can be inherited; administrators must still grant and consent to the underlying permissions.

    $GraphResourceAppId = "00000003-0000-0000-c000-000000000000"
    
    $InheritanceBody = @{
      resourceAppId = $GraphResourceAppId
      inheritableScopes = @{
        "@odata.type" = "#microsoft.graph.allAllowedScopes"
        kind = "allAllowed"
      }
      inheritableRoles = @{
        "@odata.type" = "#microsoft.graph.allAllowedRoles"
        kind = "allAllowed"
      }
    } | ConvertTo-Json -Depth 5
    
    Invoke-MgGraphRequest `
      -Method POST `
      -Uri "https://graph.microsoft.com/v1.0/applications/microsoft.graph.agentIdentityBlueprint/$BlueprintObjectId/inheritablePermissions" `
      -Headers @{ "OData-Version" = "4.0" } `
      -Body $InheritanceBody `
      -ContentType "application/json"

    This shows the administration mechanism, not a recommendation to grant every Graph permission. allAllowed lets eligible permissions granted for that resource be inherited. For sensitive agents, prefer explicit grants, review inherited baselines and separate read-only and action-taking agents into different blueprints.

    Test a permitted read and a prohibited write. Least-privilege validation is incomplete until the prohibited operation fails.

    Step 7: create the Conditional Access boundary

    Use the Entra admin center so the agent-specific picker and risk controls are easy to verify:

    1. Go to Entra ID > Conditional Access > Policies > New policy.
    2. Name it CA-AI-Agents-Block-Unapproved.
    3. Under Users, agents or workload identities, select Agents.
    4. Include All agent identities.
    5. Exclude only reviewed and approved blueprints or identities.
    6. Under Target resources, include All resources.
    7. Under Grant, select Block access.
    8. Set it to Report-only and create it.

    Create a second policy for agent risk: include all agent identities and resources, select Conditions > Agent risk > High, choose Block access, and start in Report-only.

    Run representative workflows and review Conditional Access insights and sign-in logs. Move a policy to On only after proving that approved agents work and unapproved or risky agents are denied.

    Step 8: enable Microsoft Defender protection

    After onboarding to Microsoft Agent 365:

    1. Open the Microsoft Defender portal.
    2. Go to Settings > Security for AI > Get started.
    3. Confirm security for AI agents is enabled.
    4. Connect Microsoft 365 and include Microsoft Entra ID management events and Microsoft 365 activities.
    5. For Copilot Studio agents, enable real-time protection with the Power Platform administrator.
    6. Confirm the connector status is Connected.

    Without the Microsoft 365 connector, supported runtime blocking can continue, but related alerts and incidents might not appear in Defender. Monitor connector health. Under Assets > AI assets, confirm the agent appears, has an owner and has no unresolved excessive-permission findings.

    Step 9: validate and hunt

    Defender hunting schema can vary by rollout. In Advanced Hunting > Schema, search for tables containing AI, Agent or CloudApp, and prefer Microsoft-provided queries rather than guessing table names.

    Use Graph to validate the deployed identities:

    Invoke-MgGraphRequest -Method GET -Uri `
      "https://graph.microsoft.com/v1.0/applications/microsoft.graph.agentIdentityBlueprint/$BlueprintObjectId"
    
    Invoke-MgGraphRequest -Method GET -Uri `
      "https://graph.microsoft.com/v1.0/servicePrincipals/$AgentObjectId"
    
    $FilterName = [uri]::EscapeDataString("displayName eq '$AgentName'")
    Invoke-MgGraphRequest -Method GET -Uri `
      "https://graph.microsoft.com/v1.0/servicePrincipals?`$filter=$FilterName&`$select=id,displayName,accountEnabled,servicePrincipalType"

    Complete these tests:

    Test Expected result
    Approved agent performs allowed read Token and API request succeed
    Agent attempts prohibited write Target API returns access denied
    Unapproved agent targets protected resource Report-only event first; blocked after enforcement
    Prompt requests a credential Agent refuses; no secret in output or logs
    Prompt requests an unapproved tool Tool gateway denies invocation
    Defender connector is interrupted Operational monitoring alerts
    Agent identity is disabled New token acquisition fails

    Use test identities and synthetic data. Do not run destructive simulations in production.

    Step 10: enforce every tool call in code

    Identity controls decide who may request access. Application code must still authorise each tool invocation:

    if tool not in approved_tools:
        deny("Tool is not approved")
    
    if requested_resource not in approved_resources:
        deny("Resource is outside the approved boundary")
    
    if action in [delete, publish, send_external, change_permission]:
        require_human_approval()
    
    execute_with_agent_identity()
    write_immutable_audit_event()

    Never use the system prompt as the only authorisation control. Log agent object ID, blueprint, calling user when applicable, tool, target, approval reference, result and correlation ID. Avoid full prompts or outputs when they contain sensitive data.

    Step 11: protect the data

    Apply Microsoft Purview sensitivity labels and data-loss-prevention policies where the platform and data path support them. For each source, document:

    • which classifications the agent may read;
    • whether output inherits source classification;
    • allowed destinations and external-sharing restrictions;
    • retention and deletion requirements; and
    • whether prompts and responses are collected for monitoring.

    Test with synthetic labelled documents. Confirm the agent cannot move protected content to an unapproved destination and that blocked attempts produce investigation evidence.

    Step 12: containment and recovery

    For a single affected agent, disable the child service principal:

    Update-MgServicePrincipal `
      -ServicePrincipalId $AgentObjectId `
      -AccountEnabled:$false
    
    Get-MgServicePrincipal -ServicePrincipalId $AgentObjectId |
      Select-Object Id, DisplayName, AccountEnabled

    Re-enable only after investigation and approval:

    Update-MgServicePrincipal `
      -ServicePrincipalId $AgentObjectId `
      -AccountEnabled:$true

    Disabling the blueprint principal provides a broader kill switch for its child identities. Your incident runbook should also stop the deployment and tool gateway, remove affected permissions, preserve logs, identify actions, rotate downstream credentials, correct the weakness and require owner approval before recovery.

    Already-issued tokens can remain valid until expiry or resource-side revocation takes effect. A tool-gateway kill switch adds immediate application-level containment.

    Production checklist

    • Named business owner, technical owner and sponsor
    • Purpose, environment, expiry and review date recorded
    • Dedicated identity created from an Agent ID blueprint
    • Managed identity federation or certificate authentication
    • Effective permissions documented and tested
    • Prohibited write test fails
    • Conditional Access evaluated in report-only mode
    • High-risk agent policy tested
    • Agent visible in Defender inventory
    • Connector health monitored
    • Tool calls enforced outside the model
    • Human approval for consequential actions
    • Purview/DLP tested with synthetic data
    • Single-agent and blueprint containment tested

    Common mistakes

    Creating a normal app registration and calling it an agent. Use a blueprint and agent identity so sponsorship, lifecycle and audit semantics are available.

    Giving the agent a shared administrator account. Use a dedicated non-human identity and the minimum resource access.

    Treating inherited permissions as harmless. A broad blueprint baseline affects current and future child identities.

    Enabling blocking immediately. Use report-only mode, review impact, test approved and denied paths, then enforce.

    Logging every prompt without a data review. Observability can contain confidential input and output. Agree collection, access, retention and regional requirements.

    Using the prompt as an access-control list. Enforce tools and resources in code and at the target API.

    Tested scope and limitations

    These commands follow Microsoft Graph v1.0 Agent ID endpoints and Microsoft documentation available on 19 September 2026. They use placeholders and were syntax-reviewed but were not executed against the reader’s tenant. Roles, licences, preview availability, Defender schema and portal labels can differ.

    Test in a non-production tenant. Microsoft recommends the Microsoft 365 Agents SDK for new projects because it handles identity creation and Agent 365 registration. If provisioning directly through Graph, also register the agent in the Agent 365 registry so administrators can discover and govern it.

    References