Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deploy Agent + Agent ID using Entra SDK + App Service

Reference implementation that hosts a Microsoft Entra Agent Identity demo on Azure App Service for Linux using the sidecar containers feature. The same demo is commonly run on Azure Container Apps; this repo shows how to do it on App Service instead.

The app proves Entra Agent Identity end-to-end with 5 clickable steps:

  1. Get a Bearer token as the Agent Identity (not as the Blueprint).
  2. Decode the JWT and verify Agent-specific claims (xms_par_app_azp, idtyp=app, etc.).
  3. Call Microsoft Graph /v1.0/users?$top=3 as the Agent.
  4. Negative comparison — same Graph call without AgentIdentity (token reverts to Blueprint).
  5. Security boundary — try to mint a token for an Agent parented by a different Blueprint and watch Entra reject it (AADSTS700213).

Architecture

User (browser)
    │ HTTPS
    ▼
┌─────────────────────────────────────────┐
│ App Service (Linux, custom container)   │
│                                         │
│  main: agent (FastAPI, port 8000) ──▶  │
│                                         │
│  sidecar: entra-sdk auth-sidecar (5000) │
│                                         │
└──────────────────┼──────────────────────┘
                   │ OAuth client_credentials + AgentIdentity
                   ▼
       login.microsoftonline.com → graph.microsoft.com
  • Main container — your FastAPI app, built from this repo's Dockerfile and pushed to ACR.
  • Sidecar containermcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0-azurelinux3.0-distroless.
  • They share localhost, so the agent reaches the sidecar at http://localhost:5000.

Files

File Purpose
app.py FastAPI app — backend routes + embedded HTML/JS for the 5-step UI
Dockerfile python:3.12-slim + fastapi + uvicorn + httpx, exposes 8000
.env.example Template for runtime env vars
deploy.ps1 One-shot Azure deployment (RG → Plan → Web App → sidecar)
README.md This file

Prerequisites

  • Azure CLI (az) logged into your tenant.
  • An Azure subscription where you can create resource groups and App Service plans.
  • An Azure Container Registry with the agent image pushed (e.g. <YOUR_ACR>.azurecr.io/agent-demo:v1). Build & push from this folder:
    az acr build -r <YOUR_ACR> -t agent-demo:v1 .
  • Entra app registrations already created:
    • A Blueprint app (the credential holder).
    • An Agent Identity app (credential-less child of the Blueprint).
    • Optionally, a foreign Agent app under a different Blueprint, for Step 5's negative test.

Configure

Edit the variables at the top of deploy.ps1:

Variable What it is
$Subscription Azure subscription ID
$ResourceGroup RG to create / reuse
$WebAppName Globally unique under *.azurewebsites.net
$AcrName Your ACR name (without .azurecr.io)
$ImageTag Tag of the agent image to deploy
$TenantId Entra tenant where the Blueprint and Agent live
$BlueprintAppId App (client) ID of the Blueprint
$AgentAppId App (client) ID of the Agent Identity
$ForeignAgentAppId App ID of a foreign Agent (optional, for Step 5)
$UseManagedIdentityForAcr $true for managed-identity ACR pull (preferred), $false for ACR admin user fallback

Deploy

az login --tenant <YOUR_TENANT_ID>
.\deploy.ps1

The script:

  1. Creates the resource group.
  2. Creates a Linux App Service Plan (B1 — sidecars require Basic+).
  3. Creates a Web App with the agent image as the main container.
  4. Configures ACR pull (managed identity or admin credentials).
  5. Sets app settings (TENANT_ID, BLUEPRINT_APP_ID, AGENT_APP_ID, FOREIGN_AGENT_APP_ID, SIDECAR_URL=http://localhost:5000, WEBSITES_PORT=8000).
  6. Adds the auth-sidecar sidecar container on port 5000.
  7. Restarts and prints the URL.

Update after editing app.py

az acr build -r <YOUR_ACR> -t agent-demo:vNEXT .
az webapp config container set -g <YOUR_RG> -n <YOUR_WEBAPP> `
  --container-image-name <YOUR_ACR>.azurecr.io/agent-demo:vNEXT
az webapp restart -g <YOUR_RG> -n <YOUR_WEBAPP>

Tear down

az group delete --name <YOUR_RG> --yes --no-wait

Why App Service (vs. Container Apps)?

Aspect Container Apps App Service
Multi-container Native containers[] Sidecar containers feature (GA)
Hostname *.azurecontainerapps.io *.azurewebsites.net
Scale-to-zero Yes (KEDA) No on B1; needs scale rules on Premium
Min plan tier Consumption B1 (sidecars require Basic+)
App code identical
Entra config identical

The application code, env-var contract, and 5-step UX are identical across both hosting models. Only the deployment plumbing differs.

Troubleshooting

  • ACRTokenRetrievalFailure / ImagePullFailure — your account doesn't have Microsoft.Authorization/roleAssignments/write on the ACR. Either ask the ACR owner to grant AcrPull to the web app's managed identity, or set $UseManagedIdentityForAcr = $false to use ACR admin credentials.
  • Application Error after deploy — check az webapp log tail -g <RG> -n <WEBAPP>. Most common causes: image pull failure (above), missing env vars, or sidecar not yet started.
  • Sidecar didn't start — list sidecars with az webapp sitecontainers list -g <RG> -n <WEBAPP> -o table.

Security notes

  • .env is gitignored. Never commit real tenant / app IDs or secrets.
  • The Agent Identity is credential-less by design — only the Blueprint holds a secret, and the sidecar uses it together with AgentIdentity={agentAppId} to request Agent-scoped tokens from Entra.
  • Step 5 (security boundary) demonstrates that a Blueprint cannot mint tokens for Agents it does not parent — Entra enforces this server-side.

About

Deploy Agent + Entra Agent ID demo on Azure App Service (Linux + sidecar containers)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages