Skip to content

About

PoC: Entra Agent Identity (delegated User pattern) authenticating an AI agent to Azure DevOps REST API via FIC token exchange sidecar.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Agent ID + Azure DevOps — AI Agent Demo

This proof-of-concept demonstrates Microsoft Entra Agent ID (delegated user pattern) authenticating an AI agent to Azure DevOps REST API — without PATs, API keys, or stored secrets for ADO access.

The AI agent (powered by Azure OpenAI with function calling) can:

  • ✅ Create work items (Issues)
  • ✅ Push file changes to new branches
  • ✅ Create pull requests

All authentication to Azure DevOps is handled by the Entra SDK Auth Sidecar using the Agent ID User (delegated) flow.

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│  Docker Compose (internal network only)                             │
│                                                                     │
│  ┌────────────────────────┐        ┌────────────────────────────┐   │
│  │  Entra SDK Sidecar     │◄───────│  AI Agent (Flask + OpenAI) │   │
│  │  (token management)    │────────►                            │   │
│  │                        │        │  • Chat UI                 │   │
│  │  mcr.microsoft.com/    │        │  • Function calling loop   │   │
│  │  entra-sdk/auth-sidecar│        │  • ADO REST API tools      │   │
│  └────────────────────────┘        └────────────────────────────┘   │
│           │                                      │                  │
│           │ FIC token exchange                   │ Bearer token     │
│           ▼                                      ▼                  │
│  ┌───────────────────────┐        ┌─────────────────────────────┐   │
│  │  Microsoft Entra ID   │        │  Azure DevOps REST API      │   │
│  │  (login.microsoft.com)│        │  (dev.azure.com)            │   │
│  └───────────────────────┘        └─────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

Identity Flow

  1. Sidecar authenticates to Entra ID using Blueprint app credentials
  2. Agent requests token: GET /AuthorizationHeaderUnauthenticated/AzureDevOps?AgentIdentity={id}&AgentUsername={upn}
  3. Sidecar performs Federated Identity Credential (FIC) token exchange
  4. Returns Bearer token scoped to Azure DevOps (499b84ac-1321-427f-aa17-267ca6975798)
  5. Agent calls ADO REST API as the specified user

Security Note: The AgentUsername is configured via environment variable — it is NOT user-supplied. The sidecar is only accessible within the Docker network (no host port exposure).

Prerequisites

1. Entra ID Configuration

Component Description
Blueprint App App registration that acts as the "factory" for Agent Identity tokens
Agent Identity Service principal (the individual agent)
Agent User A user in your Entra tenant that the agent acts on behalf of
FIC Configuration Federated Identity Credential linking Blueprint → Agent → User

Agent Identity delegated permissions

The Agent Identity (the parent of the Agent User) must hold the following delegated permissions, scoped only to the Agent User:

Resource Scope
Azure DevOps user_impersonation
Microsoft Graph openid profile email offline_access

How to grant — these grants can only be created today via Microsoft Graph by POSTing an oAuth2PermissionGrant (one per resource, two total). Use these exact field values:

Field Value
consentType Principal (per-user — not AllPrincipals)
clientId Object ID of the Agent Identity service principal (not the Blueprint, not the User)
principalId Object ID of the Agent User
resourceId Object ID of the resource's Enterprise App service principal in your tenant (Microsoft Graph SP for the Graph grant; Azure DevOps SP for the ADO grant)
scope Space-separated scope value from the table above

2. Azure DevOps

  • Organization must be backed by the same Entra tenant
  • The Agent User must be a member of the ADO organization
  • The Agent User needs:
    • Access level: Basic (Stakeholders cannot access Code/Repos)
    • Work Items: Read/Write on the target project
    • Code: Contribute to the target repository
    • Pull Requests: Create on the target repository

3. Azure OpenAI

  • Deployed model with function calling support (GPT-4o recommended)
  • API key and endpoint

4. Docker

  • Docker Desktop or equivalent container runtime

Quick Start

  1. Clone this repository:

    git clone <this-repo-url>
    cd agentid-azuredevops
  2. Configure environment:

    cp .env.example .env
    # Edit .env with your values
  3. Run:

    docker compose --env-file .env up --build
  4. Open the chat UI: http://localhost:4192

  5. Try a prompt:

    "Create an issue titled 'Update documentation', then add a file called docs/getting-started.md with a brief guide, and create a pull request for it. Request review from user@contoso.com"

Sample Prompts

Prompt What it does
"Create an issue titled 'Fix login timeout'" Creates a work item assigned to the agent
"Push a file called hello.txt with 'Hello World' to a new branch and open a PR" Full branch + commit + PR flow
"Create a PR for branch feature/docs and ask john@contoso.com to review" PR with reviewer assignment
"Check comments on PR #12 and reply to any feedback" Reads threads and responds
"What comments are on PR #5?" Lists all review comments
"Reply to the reviewer on PR #12 thread 3 saying we'll fix it in the next commit" Targeted reply

Configuration Reference

See .env.example for all configuration options.

Variable Description
TENANT_ID Your Entra tenant ID
BLUEPRINT_APP_ID Blueprint app registration client ID
BLUEPRINT_CLIENT_SECRET Blueprint app secret (dev only)
AGENT_APP_ID Agent Identity service principal client ID
AGENT_USERNAME UPN of the agent user (e.g. agent@contoso.com)
AZURE_OPENAI_ENDPOINT Azure OpenAI endpoint URL
AZURE_OPENAI_API_KEY Azure OpenAI API key
AZURE_OPENAI_DEPLOYMENT Model deployment name
ADO_ORG Azure DevOps organization name
ADO_PROJECT Target project name
ADO_REPO Target repository name

How It Works

Function Calling Flow

User message → Azure OpenAI (with tool definitions)
                    │
                    ▼ tool_calls
         ┌───────────────────────┐
         │ execute_tool()        │
         │  1. Get token from    │
         │     sidecar           │
         │  2. Call ADO REST API │
         │  3. Return result     │
         └───────────────────────┘
                    │
                    ▼ tool results
         Azure OpenAI → final response → User

Available Tools

Tool ADO API Description
create_work_item POST /_apis/wit/workitems/$Issue Creates an Issue (auto-assigned to agent)
push_file_change POST /_apis/git/repositories/{repo}/pushes Creates branch + pushes file
create_pull_request POST /_apis/git/repositories/{repo}/pullrequests Creates a PR with optional reviewer
get_pr_threads GET /_apis/git/repositories/{repo}/pullRequests/{id}/threads Gets all comment threads
reply_to_pr_thread POST /.../threads/{id}/comments Replies to a review comment

Production Considerations

This is a demo/PoC. For production deployments:

  • Replace ClientSecret with SignedAssertionFilePath (AKS Workload Identity) or SignedAssertionFromManagedIdentity
  • Use the sidecar to also authenticate Azure OpenAI (scope: https://cognitiveservices.azure.com/.default)
  • Add proper error handling, retries, and circuit breakers
  • Implement audit logging for all ADO operations
  • Consider rate limiting on the chat endpoint
  • Add input validation and sanitization

Related Resources

License

MIT

About

PoC: Entra Agent Identity (delegated User pattern) authenticating an AI agent to Azure DevOps REST API via FIC token exchange sidecar.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages