Share via


Sign in users and call downstream APIs with the Microsoft Entra SDK for AgentID in Python

In this quickstart, you use a sample web app to learn how to sign in users or agents and call downstream APIs by using its own identity. The sample app uses the Microsoft Entra SDK for AgentID to validate user tokens for delegated access and uses application identity for service-to-service communication with downstream APIs like Microsoft Graph.

Prerequisites

  • Install the UV package manager. UV is a fast Python package installer and resolver written in Rust.

  • Install Docker Desktop.

  • An Azure account with an active subscription. If you don't already have one, Create an account for free.

  • This Azure account must have permissions to manage applications. Any of the following Microsoft Entra roles include the required permissions:

    • Application Administrator
    • Application Developer
  • A workforce tenant. You can use your Default Directory or set up a new tenant.

Create and configure your Microsoft Entra application

To complete the rest of the quickstart, you need to first register an application in Microsoft Entra ID.

Create application registration

Follow these steps to create the app registration:

  1. Sign in to the Microsoft Entra admin center as at least an Application Developer.

  2. If you have access to multiple tenants, use the Settings icon in the top menu to switch to the tenant in which you want to register the application.

  3. Browse to Entra ID > App registrations and select New registration.

  4. Enter a meaningful Name for your app, such as identity-client-app. App users see this name, and you can change it at any time. You can have multiple app registrations with the same name.

  5. Under Supported account types, specify who can use the application. Select Accounts in this organizational directory only for most applications. Refer to the table for more information on each option.

    Supported account types Description
    Accounts in this organizational directory only For single-tenant apps for use only by users (or guests) in your tenant.
    Accounts in any organizational directory For multitenant apps and you want users in any Microsoft Entra tenant to be able to use your application. Ideal for software-as-a-service (SaaS) applications that you intend to provide to multiple organizations.
    Accounts in any organizational directory and personal Microsoft accounts For multitenant apps that support both organizational and personal Microsoft accounts (for example, Skype, Xbox, Live, Hotmail).
    Personal Microsoft accounts For apps used only by personal Microsoft accounts (for example, Skype, Xbox, Live, Hotmail).
  6. Select Register to complete the app registration.

    Screenshot of Microsoft Entra admin center in a web browser, showing the Register an application pane.

  7. The application's Overview page is displayed. Record the following values from the application Overview page for later use:

    • Application (client) ID
    • Directory (tenant) ID

    Screenshot of the Microsoft Entra admin center in a web browser, showing an app registration's Overview pane.

Add a redirect URI

The Python sample app uses interactive authentication with a browser-based sign-in flow. Configure a redirect URI to handle the authentication response:

  1. In your app registration, under Manage, select Authentication.
  2. Select Add a platform.
  3. Select Mobile and desktop applications.
  4. Under Custom redirect URIs, enter http://localhost.
  5. Select Configure.

Add client credentials

The Microsoft Entra SDK for AgentID uses client credentials to authenticate and get tokens for downstream APIs. For local development and testing, use a self-signed certificate for authentication.

Generate a self-signed certificate

Run PowerShell as an administrator and use the following commands to generate a self-signed certificate:

# Generate a self-signed certificate
$cert = New-SelfSignedCertificate `
    -Subject "CN=AgentID-Client-Certificate" `
    -CertStoreLocation "Cert:\CurrentUser\My" `
    -KeyExportPolicy Exportable `
    -KeySpec Signature `
    -KeyLength 2048 `
    -KeyAlgorithm RSA `
    -HashAlgorithm SHA256 `
    -NotAfter (Get-Date).AddDays(7)

# Export public key (CER) for upload to Azure
$cerPath = "agentid-client-certificate.cer"
Export-Certificate -Cert $cert -FilePath $cerPath

# Export private key (PFX) for the Agent ID SDK container
$pfxPath = "agentid-client-certificate.pfx"
$certPassword = ConvertTo-SecureString -String "YourSecurePassword123!" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath $pfxPath -Password $certPassword


Write-Host "Certificate generated successfully!"
Write-Host "CER file (public key): $cerPath"
Write-Host "PFX file (private key): $pfxPath"
Write-Host "Certificate Thumbprint: $($cert.Thumbprint)"
Write-Host "Certificate Password: YourSecurePassword123!"

Record the certificate thumbprint displayed in the PowerShell output. You need it to verify the certificate in the Microsoft Entra admin center matches the one installed locally.

Upload the certificate to Microsoft Entra ID

Follow these steps to upload the .cer file created in your current directory to the Microsoft Entra admin center:

  1. Open your app registration in the Microsoft Entra admin center
  2. Under Manage, select Certificates & secrets.
  3. In the Certificates tab, select Upload certificate.
  4. Select the .cer file you generated (for example, agentid-client-cert.cer).
  5. Provide a description (for example, "AgentID Local Development Certificate").
  6. Select Add.
  7. Record the certificate Thumbprint displayed (it should match the one from your certificate generation).

Note

For production environments, use certificates issued by a trusted Certificate Authority (CA) and store them in Azure Key Vault with managed identity access. Use self-signed certificates only for local development and testing.

Configure API permissions

Follow these steps to configure delegated permissions to Microsoft Graph. With these permissions, your client application can perform operations on behalf of the signed-in user, such as reading their email.

  1. In your app registration, under Manage, select API permissions > Add a permission > Microsoft Graph.
  2. Select Delegated permissions. Microsoft Graph exposes many permissions, with the most commonly used shown at the top of the list.
  3. Under Select permissions, select and add User.Read.

Configure application permissions

To test application-only flows where the AgentID SDK calls APIs by using its own identity (without a user context), configure application permissions:

  1. From the API permissions page, select Add a permission > Microsoft Graph.
  2. Select Application permissions.
  3. Under Select permissions, search for and select User.Read.All.
  4. Select Add permissions.
  5. Select Grant admin consent for [Your Tenant] and confirm.

Note

Application permissions require administrator consent. Without this step, the application-only endpoints in the testing section fail.

Expose an API (for token validation testing)

To call the AgentID SDK's /validate endpoint with tokens issued specifically for your application (using the api://<application-client-id>/access_as_user scope), you must complete this step. If you're only testing Microsoft Graph scenarios with delegated permissions, you can skip this section. Follow these steps to expose an API containing the required scopes:

  1. Under Manage, select Expose an API.

  2. At the top of the page, select Add next to Application ID URI. This value defaults to api://<application-client-id>. The App ID URI acts as the prefix for the scopes you'll reference in your API's code, and it must be globally unique. Select Save.

  3. Select Add a scope as shown:

    Screenshot of an app registration's Expose an API pane in the Microsoft Entra admin center.

  4. Next, specify the scope's attributes in the Add a scope pane, as follows:

    • Scope name: access_as_user
    • Who can consent: Admins and users
    • Admin consent display name: Access the AgentID SDK as user
    • Admin consent description: Allow access to AgentID SDK APIs as the signed-in user
    • State: Enabled
  5. Select Add scope.

Start the Microsoft Entra SDK for AgentID

The Microsoft Entra SDK for AgentID is a containerized web service that handles token acquisition, validation, and secure downstream API calls. It runs as a companion container alongside your application, allowing you to offload identity logic to a dedicated service.

Create a configuration file

The AgentID SDK requires a configuration file to connect to your Microsoft Entra application. Create a new directory for your configuration and create an appsettings.json file:

# Create a directory for the AgentID SDK configuration
New-Item -ItemType Directory -Path "agentid-config" -Force
cd agentid-config

# Create the appsettings.json file
New-Item -ItemType File -Path "appsettings.json"

Open appsettings.json in your preferred text editor and add the following configuration, replacing the placeholder values with your Microsoft Entra application details:

{
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "YOUR_TENANT_ID_HERE",
        "ClientId": "YOUR_CLIENT_ID_HERE",
        "ClientCredentials": [
            {
                "SourceType": "Path",
                "CertificateStorePath": "agentid-client-certificate.pfx",
                "CertificateDistinguishedName": "YourSecurePassword123!"
            }
        ]
    },
    "DownstreamApis": {
        "me": {
            "BaseUrl": "https://graph.microsoft.com/v1.0/",
            "RelativePath": "me",
            "Scopes": [ "User.Read" ]
        }
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    },
    "AllowedHosts": "*"
}

Pull and run the AgentID SDK container

The AgentID SDK is available as a prebuilt container image from the Microsoft Container Registry (MCR). Before pulling the container image, verify that Docker Desktop is running. If Docker isn't running, open Docker Desktop and wait for the status to show "Docker Desktop is running".

Navigate to your configuration directory and run the following commands:

# Navigate to your config directory
cd agentid-config

# Pull the AgentID SDK container image from MCR
docker pull mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0-rc.2-azurelinux3.0-distroless

# Run the container
docker run -d `
    --name agentid-sdk `
    -p 5178:8080 `
    -e ASPNETCORE_ENVIRONMENT=Development `
    mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0-rc.2-azurelinux3.0-distroless

# Copy configuration files into the container
docker cp appsettings.json agentid-sdk:/app/appsettings.json
docker cp agentid-client-certificate.pfx agentid-sdk:/app/agentid-client-certificate.pfx

# Restart the container to apply the configuration
docker restart agentid-sdk

Note

For Windows hosts, use the Windows container variant: mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0-rc.2-windows

You can manage the Agent ID SDK container by using the following Docker commands:

  • View container logs: docker logs agentid-sdk
  • View real-time logs: docker logs -f agentid-sdk
  • Stop the container: docker stop agentid-sdk
  • Start the container again: docker start agentid-sdk
  • Remove the container: docker rm agentid-sdk

Verify that the container is running

You can verify whether the AgentID SDK container is running correctly by calling the health check endpoint,/healthz:

Invoke-RestMethod -Uri "http://localhost:5178/healthz" -ErrorAction SilentlyContinue

This endpoint returns Healthy, which confirms the AgentID SDK is running correctly and ready to handle requests. Don't terminate the AgentID SDK while testing. The container must continue running in the background for all authentication and API calls from the Python app to work.

Run the Python sample app

The Python sample app demonstrates how to use the Microsoft Entra SDK for AgentID for authentication and API calls. The AgentID SDK runs as a local web service and acts as an authentication proxy. It validates user tokens and calls downstream APIs like Microsoft Graph on your behalf.

The sample includes Python scripts that show two authentication patterns:

  • Delegated permissions: The AgentID SDK validates your user token and calls APIs on behalf of the signed-in user.
  • Application permissions: The AgentID SDK uses its own identity to call APIs without a user context.

This approach centralizes token management and API access in a single service that your applications can consume through simple HTTP requests.

Clone or download the Python sample app

Download the Python sample app and extract it to a local directory. Alternatively, clone the repository by opening a command prompt, navigating to your desired project location, and running the following command:

git clone https://github.com/AzureAD/microsoft-identity-web.git
cd microsoft-identity-web/tests/DevApps/SidecarAdapter/python

The sample app contains the following Python scripts:

  • get_token.py – Acquires user access tokens through the Microsoft Authentication Library (MSAL).
  • main.py – Command-line interface that calls the AgentID SDK endpoints and displays JSON responses.
  • MicrosoftIdentityWebSidecarClient.py – HTTP client wrapper for the AgentID SDK's /Validate, /AuthorizationHeader, and /DownstreamApi endpoints.

The Python scripts use the parameter me when calling AgentID SDK endpoints. This parameter references the downstream API configuration named "me" in the AgentID SDKs appsettings.json:

"DownstreamApis": {
    "me": {
        "BaseUrl": "https://graph.microsoft.com/v1.0/",
        "RelativePath": "me",
        "Scopes": [ "User.Read" ]
    }
}

When you call an AgentID SDK endpoint with the me parameter, the SDK uses the base URL and relative path from the configuration to construct the full API endpoint, requests the specified scopes, and calls the Microsoft Graph /me endpoint to retrieve the signed-in user's profile. You can add additional downstream API configurations to appsettings.json with different names and endpoints to call additional APIs.

Test interaction between the Microsoft Entra SDK for AgentID and the Python app

This quickstart demonstrates a three-tier authentication pattern:

  1. User authentication: You acquire a user access token by using MSAL for Python. This token proves the user's identity.
  2. Token validation: The AgentID SDK validates the user token to ensure it's authentic and issued for your application.
  3. Token exchange: The AgentID SDK uses the On-Behalf-Of (OBO) flow to exchange the user token for a new token scoped to Microsoft Graph, then calls the API.

For application-only scenarios, the AgentID SDK bypasses user authentication and uses its own client credentials to acquire tokens directly. The SDK centralizes this authentication logic, so your Python application only needs to make simple HTTP requests without managing complex OAuth flows.

Acquire a user access token

Before testing the AgentID SDK endpoints, obtain a valid access token. The get_token.py script uses MSAL for Python to acquire tokens interactively through a browser-based sign-in flow.

Token scopes and audiences:

The scope you request determines the token's audience (aud claim), which must match the endpoint you're calling:

  • For token validation testing, use api://<client-id>/access_as_user to test the /validate endpoint
  • For Microsoft Graph testing, acquire a new token with User.Read scope to test /authorizationheader and /downstreamapi endpoints

Use the following commands to set your configuration variables and acquire a token:

# Set your configuration
$clientId = "YOUR_CLIENT_ID_HERE"
$tenantId = "YOUR_TENANT_ID_HERE"
$authority = "https://login.microsoftonline.com/$tenantId"

# For testing AgentID SDK APIs (if you exposed the API)
$scope = "api://$clientId/access_as_user"

# Or for testing Microsoft Graph directly
# $scope = "User.Read"

# Acquire token
$token = uv run --with msal get_token.py --client-id $clientId --authority $authority --scope $scope

When you run the acquire token command, the script initiates an interactive browser-based sign-in flow. This browser authentication only occurs on the first run. After successful authentication, the token is cached locally for subsequent use. The access token is then printed to the console and stored in the $token PowerShell variable for use in subsequent commands.

Test the Microsoft Entra SDK for AgentID endpoints with delegated permissions

After you get a valid user token, you can test the AgentID SDK core endpoints. These operations use delegated permissions, so the SDK acts on behalf of the signed-in user.

First, set the SDK's base URL:

$side_car_url = "http://localhost:5178"

1. Validate the user token

The /validate endpoint requires a token issued specifically for your application by using the api://<client-id>/access_as_user scope. Before you test token validation, ensure you complete the steps in the "Expose an API" section. Use the following command to call the /validate endpoint.

uv run --with requests main.py --base-url $side_car_url --authorization-header "Bearer $token" validate

Expected response:

The /validate endpoint checks that the token is valid and extracts claims information:

{
  "protocol": "Bearer",
  "token": "eyJ0eXAiOiJKV1QiLCJub25jZSI6...",
  "claims": {
    "aud": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "iss": "https://login.microsoftonline.com/...",
    "name": "Your Name",
    "upn": "your.email@domain.com"
  }
}

This response confirms that:

  • The token format is correct (Bearer token)
  • The token is issued by the expected authority
  • The audience (aud) matches your application
  • User identity claims are present and valid

2. Get an authorization header for Microsoft Graph

The /authorizationheader endpoint retrieves a properly formatted authorization header for calling downstream APIs:

uv run --with requests main.py --base-url $side_car_url --authorization-header "Bearer $token" get-auth-header me

This endpoint:

  • Validates the incoming user token
  • Acquires a new token for Microsoft Graph on behalf of the user
  • Returns the formatted authorization header

3. Call Microsoft Graph through the Microsoft Entra SDK for AgentID

The /downstreamapi endpoint calls Microsoft Graph directly and returns the response:

uv run --with requests main.py --base-url $side_car_url --authorization-header "Bearer $token" invoke-downstream me

Expected response:

{
  "statusCode": 200,
  "headers": {...},
  "content": {
    "displayName": "Your Name",
    "mail": "your.email@domain.com",
    "userPrincipalName": "your.email@domain.com"
  }
}

The me parameter corresponds to the downstream API configuration you defined in appsettings.json. The AgentID SDK:

  1. Validates your user token
  2. Acquires a new token for Microsoft Graph by using the on-behalf-of (OBO) flow
  3. Calls the /me endpoint on Microsoft Graph
  4. Returns the user profile data

4. Override default scopes and supply a request body

You can customize API calls by overriding the default scopes configured in appsettings.json or by providing a request body for write operations.

uv run --with requests main.py --base-url $side_car_url --authorization-header "Bearer $token" --scope <scopes> invoke-downstream <api-name> --body-file <path-to-file>

This approach is useful when:

  • Testing different permission levels. For example, you can specify different scopes like --scope User.Read Mail.Read to request additional permissions
  • The downstream API requires scopes not configured by default
  • You need to request additional permissions dynamically
  • When calling APIs that require a request body (such as creating or updating resources), you add the optional --body-file parameter used for POST/PUT operations

Test application-only endpoints

The Microsoft Entra SDK for AgentID also supports application-only flows. In these flows, the AgentID SDK uses its own app identity instead of acting on behalf of a user. These endpoints don't require a user authorization header.

Note

Application-only flows require that your app registration has application permissions (such as User.Read.All) in Microsoft Entra ID, not just delegated permissions. An administrator must grant consent to these permissions before you can test these endpoints.

Get authorization header without user context

Use this endpoint to retrieve an authorization header for calling Microsoft Graph with the AgentID SDK's own identity:

uv run --with requests main.py --base-url $side_car_url get-auth-header-unauth me

This endpoint:

  • Uses the AgentID SDK's client credentials (app identity) to authenticate.
  • Acquires an app-only access token for Microsoft Graph
  • Returns the authorization header

Call Microsoft Graph without user context

Use this endpoint to call Microsoft Graph directly by using the AgentID SDK identity:

uv run --with requests main.py --base-url $side_car_url invoke-downstream-unauth me

This example demonstrates service-to-service communication where:

  • No user is involved in the authentication flow
  • The AgentID SDK authenticates by using its own client ID and certificate
  • The API call uses application permissions, not delegated permissions
  • This pattern is ideal for background services, batch processing, or automated tasks

Understand the responses

Token validation response structure

The validation response provides detailed information about the token:

Field Description
protocol The authentication scheme (always "Bearer" for OAuth 2.0 tokens)
token The original access token (truncated in examples)
claims Key-value pairs extracted from the token's payload
claims.aud The intended audience (your client ID)
claims.iss The token issuer (Microsoft Entra ID)
claims.name The display name of the signed-in user
claims.upn User Principal Name (email address)

Microsoft Graph call response structure

Field Description
statusCode HTTP status code from Microsoft Graph (200 = success)
headers Response headers from the API call
content The actual data returned by Microsoft Graph
content.displayName User's display name in the directory
content.mail User's email address
content.userPrincipalName User's UPN

Troubleshooting common issues

If you encounter errors when testing the Microsoft Entra SDK for AgentID endpoints, check the following solutions to common issues:

Issue Solution
"Connection refused" errors Verify the AgentID SDK container is running: docker ps -a. If the container status shows "Exited", check the logs: docker logs agentid-sdk. Restart the container: docker start agentid-sdk and test the health endpoint: Invoke-RestMethod -Uri "http://localhost:5178/healthz".
Container returns 500 Internal Server Error View container logs for detailed errors: docker logs agentid-sdk. Common causes: invalid JSON in appsettings.json, incorrect certificate path, wrong certificate password, or missing TenantId/ClientId values.
Certificate not found errors Ensure the PFX file was copied correctly: docker exec agentid-sdk ls -la /app/agentid-client-certificate.pfx. If missing, copy it again: docker cp agentid-client-certificate.pfx agentid-sdk:/app/agentid-client-certificate.pfx and restart: docker restart agentid-sdk.
"Invalid token" or "Audience validation failed" errors Ensure your token's audience (aud claim) matches your client ID. For the /validate endpoint, use the api://<client-id>/access_as_user scope. For Microsoft Graph calls, use User.Read. Clear the token cache: Remove-Item -Path "$env:USERPROFILE\.msal_token_cache.bin" -ErrorAction SilentlyContinue.
appsettings.json not loading Verify the file was copied into the container: docker exec agentid-sdk cat /app/appsettings.json. Ensure the JSON is valid (no comments, proper syntax). If the file is missing or incorrect, copy it again and restart the container.
Container won't start after configuration changes Stop and remove the container: docker stop agentid-sdk && docker rm agentid-sdk. Run the container again with updated configuration files following the "Pull and run the AgentID SDK container" section.

Next steps

  • Agent identities: Learn how to use the Microsoft Entra SDK for AgentID with service principals and managed identities by testing with --agent-identity and --agent-username parameters
  • Custom APIs: Add more downstream API configurations to appsettings.json to call your own protected APIs
  • Production deployment: Configure the Microsoft Entra SDK for AgentID to use managed identities instead of certificates