Share via


Comparison: Microsoft Entra SDK for AgentID vs. In-Process Microsoft.Identity.Web

This guide helps you identify the differences between the Microsoft Entra SDK for AgentID and the in-process Microsoft.Identity.Web library for handling authentication in your applications. The Microsoft.Identity.Web library integrates directly into .NET applications for maximum performance, while the Microsoft Entra SDK for AgentID runs as a separate container and supports any programming language via HTTP APIs, and choosing the correct approach depends on your application's architecture, language, and deployment environment.

Architectural differences

The fundamental difference lies in where authentication logic executes. Microsoft.Identity.Web runs within your application process, while the Microsoft Entra SDK for AgentID operates as an independent service alongside your application. This architectural choice impacts factors such as development workflow and operational complexity.

Aspect Microsoft.Identity.Web (In-Process) Microsoft Entra SDK for AgentID (Out-of-Process)
Process Boundary Shares the same process, memory, and lifecycle as your application, enabling direct method calls and shared configuration Maintains complete isolation, communicating only through HTTP APIs and managing its own resources independently
Language Coupling Tightly couples your authentication strategy to .NET, requiring C# experience and .NET runtime everywhere you need authentication Decouples authentication from your application's technology stack, exposing a language-agnostic HTTP interface that works equally well with Python, Node.js, Go, or any HTTP-capable language
Deployment Model Deploys as NuGet packages embedded in your application binary, creating a monolithic deployment unit Deploys as a separate container image, enabling independent versioning, scaling, and updates of authentication logic without impacting your application code

Microsoft.Identity.Web (In-Process)

This code snippet shows how Microsoft.Identity.Web integrates directly into an ASP.NET Core application:

// Startup configuration
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDownstreamApi("Graph", Configuration.GetSection("DownstreamApis:Graph"))
    .AddInMemoryTokenCaches();

// Usage in controller
public class MyController : ControllerBase
{
    private readonly IDownstreamApi _downstreamApi;
    
    public MyController(IDownstreamApi downstreamApi)
    {
        _downstreamApi = downstreamApi;
    }
    
    public async Task<ActionResult> GetUserData()
    {
        var user = await _downstreamApi.GetForUserAsync<User>("Graph", 
            options => options.RelativePath = "me");
        return Ok(user);
    }
}

Microsoft Entra SDK for AgentID (Out-of-Process)

This code snippet demonstrates how to call the Microsoft Entra SDK for AgentID from a Node.js application using HTTP. The call to the SDK's /DownstreamApi endpoint handles token acquisition and downstream API calls, including passing the incoming token for OBO flows in the Authorization header:

// Configuration
const SidecarUrl = process.env.SIDECAR_URL || "http://localhost:5000";

// Usage in application
async function getUserData(incomingToken: string) {
  const response = await fetch(
    `${SidecarUrl}/DownstreamApi/Graph?optionsOverride.RelativePath=me`,
    {
      headers: {
        'Authorization': `Bearer ${incomingToken}`
      }
    }
  );
  
  const result = await response.json();
  return JSON.parse(result.content);
}

Feature Comparison

Feature Microsoft.Identity.Web Microsoft Entra SDK for AgentID
Language Support C# / .NET only Any language (HTTP)
Deployment In-process library Separate container
Token Acquisition ✅ Direct MSAL.NET ✅ Via HTTP API
Token Caching ✅ In-memory, ✅ distributed ✅ In-memory, ❌distributed
OBO Flow ✅ Native support ✅ Via HTTP endpoint
Client Credentials ✅ Native support ✅ Via HTTP endpoint
Managed Identity ✅ Direct support ✅ Direct support
Agent Identities ✅ Via extensions ✅ Query parameters
Token Validation ✅ Middleware ✅ /Validate endpoint
Downstream API ✅ IDownstreamApi ✅ /DownstreamApi endpoint
Microsoft Graph ✅ Graph SDK integration ⚠️ Via DownstreamApi
Performance ⚡ In-process (fastest) 🔄 HTTP overhead
Configuration appsettings.json and code appsettings.json and Environment variables
Debugging ✅ Standard .NET debugging ⚠️ Container debugging
Hot Reload ✅ .NET Hot Reload ❌ Container restart
Package Updates 📦 NuGet packages 🐳 Container images
License MIT MIT

When to Use Each Approach

Deciding between Microsoft.Identity.Web and the Microsoft Entra SDK for AgentID depends on your application's requirements, architecture, and deployment strategy. Depending on your needs, one approach may be more suitable than the other, and the following guidelines could help you make an informed decision.

Scenario Microsoft.Identity.Web (In-Process) Microsoft Entra SDK for AgentID (Out-of-Process)
Application Stack .NET applications exclusively
• ASP.NET Core Web APIs
• ASP.NET Core Web Apps
• .NET Worker Services
• Blazor applications
• Daemon apps
Multi-language microservices
• Node.js, Python, Go, Java services
• Polyglot architectures
• Non-.NET services
• Legacy systems integration
Performance Requirements Performance is critical
• High-throughput scenarios
• Latency-sensitive operations
• Every millisecond counts
Can tolerate HTTP overhead
• ~1-5ms additional latency acceptable
• Throughput not bottlenecked by auth
Integration Needs Deep integration required
• Custom MSAL.NET configuration
• Direct access to MSAL features
• Advanced token cache strategies
Standardized integration
• HTTP API sufficient
• Consistent auth patterns across services
Development Experience Rapid development
• Quick prototyping
• Hot reload for development
• Standard .NET debugging
Container-based development
• Container restart for changes
• Container debugging required
Team & Architecture Single-language stack
• Team expertise in C#/.NET
• No multi-language requirements
Technology diversity
• Mix of frameworks and languages
• Polyglot team structure
Deployment Model Monolithic deployments
• Single application deployment
• Traditional hosting models
Containerized deployments
• Kubernetes environments
• Docker Compose setups
• Service mesh architectures
Operations Coupled auth updates
• Auth changes require app rebuild
• Shared lifecycle with application
Operational benefits
• Independent scaling of auth logic
• Separate auth updates from app code
• Centralized monitoring of auth

Migration Guidance

Migrating from Microsoft.Identity.Web to Microsoft Entra SDK for AgentID

In certain scenarios, you may want to migrate an existing .NET application using Microsoft.Identity.Web to leverage the Microsoft Entra SDK for AgentID for authentication. The reasons for migration could include adopting a multi-language architecture, standardizing authentication across services, or moving to a containerized deployment model.

Careful consideration and planning is required before you do so. This section provides a high-level migration path with code examples to help you transition your application.

Caution

Microsoft doesn't recommend that you move from Microsoft.Identity.Web to the Microsoft Entra SDK for AgentID, but if you chose to do so, the following are demonstrations of similar concepts in other languages and frameworks.

Step 1: Deploy SDK Container

First you'll need to add the SDK container to your pod:

# Before: Single ASP.NET Core container
containers:
- name: app
  image: myregistry/myapp:latest

# After: App + Microsoft Entra SDK for AgentID
containers:
- name: app
  image: myregistry/myapp:latest
  env:
  - name: SIDECAR_URL
    value: "http://localhost:5000"

- name: sidecar
  image: mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0
  env:
  - name: AzureAd__TenantId
    value: "your-tenant-id"
  - name: AzureAd__ClientId
    value: "your-client-id"

Step 2: Migrate configuration

Next, you'll need to transfer your configuration from appsettings.json to environment variables:

Before (appsettings.json)

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-client-id"
  },
  "DownstreamApis": {
    "Graph": {
      "BaseUrl": "https://graph.microsoft.com/v1.0",
      "Scopes": "User.Read Mail.Read", 
      "RelativePath": "/me"
    }
  }
}

After (Kubernetes ConfigMap / Environment Variables)

apiVersion: v1
kind: ConfigMap
metadata:
  name: sidecar-config
data:
  AzureAd__Instance: "https://login.microsoftonline.com/"
  AzureAd__TenantId: "your-tenant-id"
  AzureAd__ClientId: "your-client-id"
  DownstreamApis__Graph__BaseUrl: "https://graph.microsoft.com/v1.0"
  DownstreamApis__Graph__Scopes: "User.Read Mail.Read"
  DownstreamApis__Graph__RelativePath: "/me"

Step 3: Update Application Code

Locate all instances of in-process calls to Microsoft.Identity.Web and replace them with HTTP calls to the Microsoft Entra SDK for AgentID endpoints:

Before (C# with IDownstreamApi):

public class UserController : ControllerBase
{
    private readonly IDownstreamApi _downstreamApi;
    
    public UserController(IDownstreamApi downstreamApi)
    {
        _downstreamApi = downstreamApi;
    }
    
    [HttpGet]
    public async Task<ActionResult<User>> GetMe()
    {
        var user = await _downstreamApi.GetForUserAsync<User>(
            "Graph",
            options => options.RelativePath = "me"
        );
        return Ok(user);
    }
}

After (Any language with HTTP client):

In the following snippet, we can see calls to the Microsoft Entra SDK for AgentID using the /DownstreamApi endpoint to get user data. Examples are provided in C# and TypeScript.

public class UserController : ControllerBase
{
    private readonly HttpClient _httpClient;
    private readonly string _SidecarUrl;
    
    public UserController(IHttpClientFactory httpClientFactory, IConfiguration config)
    {
        _httpClient = httpClientFactory.CreateClient();
        _SidecarUrl = config["SIDECAR_URL"];
    }
    
    [HttpGet]
    public async Task<ActionResult<User>> GetMe()
    {
        var inboundAuthorizationHeader = Request.Headers["Authorization"].ToString();
        // this validates the inbound authorization header and calls the downstream API.
        // If you don't call a downstream API, Do validate the inbound authorization header 
        // (calling the /Validate endpoint)
        var request = new HttpRequestMessage(
            HttpMethod.Get,
            $"{_SidecarUrl}/DownstreamApi/Graph?optionsOverride.RelativePath=me"
        );
        request.Headers.Add("Authorization", inboundAuthorizationHeader);
        
        var response = await _httpClient.SendAsync(request);
        var result = await response.Content.ReadFromJsonAsync<SidecarResponse>();
        var user = JsonSerializer.Deserialize<User>(result.Content);
        return Ok(user);
    }
}

TypeScript

The same logic can be implemented in TypeScript as follows:

export async function getMe(incomingToken: string): Promise<User> {
  const SidecarUrl = process.env.SIDECAR_URL!;
  
  const response = await fetch(
    `${SidecarUrl}/DownstreamApi/Graph?optionsOverride.RelativePath=me`,
    {
      headers: {
        'Authorization': incomingToken
      }
    }
  );
  
  const result = await response.json();
  return JSON.parse(result.content) as User;
}

Step 4: Remove Microsoft.Identity.Web dependencies

Once the previous steps have been completed, you can tidy your application by removing the NuGet packages used by Microsoft.Identity.Web from your project:

<!-- Remove these from .csproj -->
<PackageReference Include="Microsoft.Identity.Web" Version="..." />
<PackageReference Include="Microsoft.Identity.Web.MicrosoftGraph" Version="..." />
<PackageReference Include="Microsoft.Identity.Web.DownstreamApi" Version="..." />

If you still want to validate tokens in your app, you do not need to fully remove the original authentication configuration, although you could delegate validation entirely to the Microsoft Entra SDK for AgentID.

// Remove from Program.cs or Startup.cs
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDownstreamApi("Graph", Configuration.GetSection("DownstreamApis:Graph"))
    .AddInMemoryTokenCaches();

Step 5: Test and Validate

  1. Unit Tests: Update tests to mock HTTP calls to the SDK
  2. Integration Tests: Test SDK communication in staging
  3. Performance Tests: Measure HTTP overhead impact
  4. Security Tests: Validate token handling and network policies

Performance Considerations

SDK Overhead

The Microsoft Entra SDK for AgentID introduces HTTP communication overhead:

Performance Factor Impact Mitigation Strategy
Latency ~1-5ms per request for localhost communication Use HTTP/2 to reduce connection overhead
Throughput Limited by HTTP connection pooling Implement connection pooling to reuse HTTP connections
Memory Additional container memory overhead Ensure adequate SDK resource allocation
Request Efficiency Multiple round trips for complex operations Batch requests to combine multiple operations when possible
Token Performance Repeated token acquisition overhead Leverage SDK's token cache for optimal performance

In-Process Performance

Using Microsoft.Identity.Web has minimal overhead since it runs within the same process as your application, providing native method calls with microsecond latency and shared process memory without HTTP limitations. When performance is critical, in-process integration is the optimal choice, but the Microsoft Entra SDK for AgentID's flexibility and language-agnostic design may outweigh the performance trade-offs in many scenarios.

The following are some performance and cost comparisons for in-process usage and Microsoft Entra SDK for AgentID (Out-of-Process) usage:

Cost Considerations

Cost Factor Microsoft.Identity.Web (In-Process) Microsoft Entra SDK for AgentID (Out-of-Process)
Compute Minimal additional CPU/memory in application process Additional container resources per pod
Network No additional overhead Minimal (localhost communication)
Storage NuGet package size (~10MB) Container image storage
Management No additional overhead Container orchestration overhead

Cost Example

For 10 replicas with 128Mi/100m SDK configuration:

Resource In-Process Microsoft Entra SDK for AgentID
Memory ~0MB additional 10 × 128Mi = 1.28GB
CPU ~0% additional 10 × 100m = 1 core
Storage ~10MB per deployment Container image size per node

Support and Maintenance

Aspect Microsoft.Identity.Web Microsoft Entra SDK for AgentID
Updates NuGet package updates Container image updates
Breaking Changes Via package versioning Via container tags
Bug Fixes Compile-time integration Runtime container updates
Security Patches Rebuild application Redeploy container
Documentation Extensive .NET docs This documentation
Community Large .NET community Growing community

Hybrid Approach

You can combine both approaches within the same architecture: use Microsoft.Identity.Web for .NET services that require maximum performance, while leveraging the Microsoft Entra SDK for AgentID for non-.NET services or when you need language-agnostic authentication patterns. This hybrid strategy allows you to optimize performance where critical while maintaining consistency and flexibility across your entire service ecosystem.

An example architecture would be as follows:

graph TB
    subgraph cluster["Kubernetes Cluster"]
        subgraph netpod["<b>.NET API Pod</b>"]
            netapi["<b>.NET API</b><br/>(Microsoft.Identity.Web)"]
            style netapi fill:#0078d4,stroke:#005a9e,stroke-width:2px,color:#fff
        end
        subgraph nodepod["<b>Node.js API Pod</b>"]
            nodeapi["<b>Node.js API</b>"]
            sidecar["<b>Microsoft Entra SDK for AgentID</b>"]
            style nodeapi fill:#68a063,stroke:#4a7c45,stroke-width:2px,color:#fff
            style sidecar fill:#f2711c,stroke:#d85e10,stroke-width:2px,color:#fff
        end
    end
    style cluster fill:#f0f0f0,stroke:#333,stroke-width:3px
    style netpod fill:#e8f4f8,stroke:#0078d4,stroke-width:2px
    style nodepod fill:#e8f4e8,stroke:#68a063,stroke-width:2px

Next Steps