Microsoft.Agents.Authentication.EntraAuthSidecar
1.7.123
Prefix Reserved
See the version list below for details.
dotnet add package Microsoft.Agents.Authentication.EntraAuthSidecar --version 1.7.123
NuGet\Install-Package Microsoft.Agents.Authentication.EntraAuthSidecar -Version 1.7.123
<PackageReference Include="Microsoft.Agents.Authentication.EntraAuthSidecar" Version="1.7.123" />
<PackageVersion Include="Microsoft.Agents.Authentication.EntraAuthSidecar" Version="1.7.123" />
<PackageReference Include="Microsoft.Agents.Authentication.EntraAuthSidecar" />
paket add Microsoft.Agents.Authentication.EntraAuthSidecar --version 1.7.123
#r "nuget: Microsoft.Agents.Authentication.EntraAuthSidecar, 1.7.123"
#:package Microsoft.Agents.Authentication.EntraAuthSidecar@1.7.123
#addin nuget:?package=Microsoft.Agents.Authentication.EntraAuthSidecar&version=1.7.123
#tool nuget:?package=Microsoft.Agents.Authentication.EntraAuthSidecar&version=1.7.123
Entra ID Auth Sidecar Provider
This namespace integrates the Microsoft 365 Agents SDK with the Microsoft Entra ID Agent Container (the sidecar). Instead of acquiring tokens directly with MSAL, the SDK delegates token acquisition to the sidecar's HTTP API, so the agent process never handles secrets, certificates, or keys.
Reference spec: microsoft/Agents#606.
Why a sidecar?
- Credential-free agent code — all credential management (Managed Identity, Workload Identity, Key Vault certs, client secret for dev) lives in the sidecar.
- Language-agnostic — every language SDK talks to the same simple HTTP API rather than re-implementing MSAL flows.
- Consistent local/prod — the same container runs locally (Docker) and in production.
Components
| Type | Role |
|---|---|
SidecarHttpClient |
Reusable HTTP client for the sidecar API (internal). Builds query strings, parses { "authorizationHeader": "Bearer <token>" } responses, and surfaces RFC 7807 ProblemDetails errors. |
SidecarAuth |
Connection-level provider implementing IAccessTokenProvider and IAgenticTokenProvider. Translates each SDK token call into a sidecar request and serves repeat requests from an in-memory token cache (see Token caching). Loadable from configuration via the (IServiceProvider, IConfigurationSection) constructor. |
SidecarServiceCollectionExtensions |
AddSidecarConnections(...) DI helper that registers the SidecarHttpClient and provider. |
SidecarHealthCheck / AddSidecarHealthCheck |
ASP.NET Core IHealthCheck (and IHealthChecksBuilder extension) that probes the sidecar /healthz endpoint on demand. |
SidecarStartupHealthCheck / AddSidecarStartupProbe |
Optional IHostedService that probes the sidecar once at startup. Warn-only by default; opt into fail-fast with failOnUnreachable: true. |
SidecarConnectionSettings |
Configuration model (bound from the connection Settings) carrying ServiceName, BlueprintServiceName, Scopes, SidecarBaseUrl, RequestTimeout, RetryCount, plus inherited connection settings (ClientId, TenantId). |
Sidecar endpoint mapping
The provider uses the sidecar's unauthenticated endpoint, where {serviceName} is a downstream API configured in the sidecar:
GET /AuthorizationHeaderUnauthenticated/{serviceName}
?AgentIdentity={agentAppInstanceId}
&AgentUserId={agentUserObjectId} (delegated/agentic-user flow)
&AgentUsername={agentUserUpn} (used instead of AgentUserId when the user is a UPN)
&optionsOverride.Scopes={scope} (repeatable)
&optionsOverride.RequestAppToken=true (app-only flow)
&optionsOverride.AcquireTokenOptions.Tenant={tenantId}
IAgenticTokenProvider method |
Sidecar call |
|---|---|
GetAgenticApplicationTokenAsync |
BlueprintServiceName (default agenticblueprint) downstream API with AgentIdentity. Returns the Blueprint (agent application) token. |
GetAgenticInstanceTokenAsync |
ServiceName downstream API with AgentIdentity + RequestAppToken=true. App-only resource token for the autonomous agent. |
GetAgenticUserTokenAsync |
ServiceName downstream API with AgentIdentity + AgentUserId/AgentUsername. Resource token for the agentic user. |
GetAccessTokenAsync (connection-level IAccessTokenProvider) |
ServiceName downstream API with RequestAppToken=true. App-only connection token. |
AgentUserId (object id) and AgentUsername (UPN) are mutually exclusive; the client emits exactly one and rejects a request that sets both.
How this relates to the spec
Spec #606 (Phase 1) originally anticipated the SDK deriving the Agent Instance and Agent User tokens locally from the Blueprint token. In practice the sidecar performs the entire agentic identity chain internally (Blueprint → Instance → agentic User via federated identity) and returns the final resource token. The SDK therefore only needs to translate each call into a single sidecar request — there is no local client_credentials/user_fic exchange. This is required for agentic instance apps, which are ServiceIdentity-type service principals whose federated credentials are Entra-managed and cannot be exchanged by the client.
AgentIdentity and AgentUserId are not stored in configuration; they are extracted from the inbound activity (Recipient.AgenticAppId, Recipient.AgenticUserId) at runtime, so a single deployment can serve multiple agent identities and users.
Token caching
SidecarAuth keeps a lightweight in-memory token cache (mirroring the MSAL provider's SDK-side cache) so repeated calls for the same identity don't hit the sidecar on every turn:
- Key — the agent identity (
AgentIdentityclient id) plus the other request parameters that change the issued token: downstreamserviceName,AgentUsername/AgentUserId, tenant, app-only vs. user, and scopes. Distinct flows, users, tenants, and scope sets never share an entry. - Lifetime — the token's own JWT
expclaim when parseable, otherwise a conservative 5-minute fallback for opaque tokens. An entry is evicted once it is within 30 seconds of expiry, so callers never receive a token that expires mid-flight. - Force refresh —
GetAccessTokenAsync(..., forceRefresh: true)evicts the entry and re-acquires from the sidecar (also settingoptionsOverride.AcquireTokenOptions.ForceRefresh=trueso the sidecar bypasses its own cache).
This is in addition to the sidecar's own server-side token cache and the expiry hint surfaced to Azure.Core via GetTokenCredential().
Base URL resolution
SidecarHttpClient.ResolveBaseUrl resolves the sidecar base URL in this order:
SIDECAR_URLenvironment variable- Explicit configuration (
SidecarBaseUrl) http://localhost:5178(default — the Entra ID Agent Container's local default port)
Loopback/private-address safety check (SSRF)
Because the sidecar issues tokens for the agent's identity, the provider refuses to send requests to an arbitrary host. After resolution, the base URL must point to a loopback (localhost, 127.0.0.0/8, ::1) or private address (RFC 1918 / RFC 4193 / link-local). A public/routable address is rejected with an InvalidOperationException at construction time. This applies regardless of whether the URL came from SIDECAR_URL, the SidecarBaseUrl setting, or the default.
To intentionally target a non-private address (e.g. a sidecar reachable at a routable address inside a carefully validated private network), set BypassLocalNetworkRestriction: true in the connection Settings. This is UNSAFE and disables the SSRF guard entirely — only enable it for a network configuration you have explicitly validated, never in a default or untrusted deployment.
Configuration
Connection-level provider (replaces MSAL)
"Connections": {
"ServiceConnection": {
"Assembly": "Microsoft.Agents.Authentication.EntraAuthSidecar",
"Type": "Microsoft.Agents.Authentication.EntraAuthSidecar.SidecarAuth",
"Settings": {
"SidecarBaseUrl": "http://localhost:5178",
"ServiceName": "botframework",
"Scopes": [ "5a807f24-c9de-44ee-a3a7-329e88a00ffc/.default" ],
"RequestTimeout": "00:00:30",
"RetryCount": 3
}
}
}
| Setting | Required | Default | Description |
|---|---|---|---|
ServiceName |
No | default |
Downstream API name configured in the sidecar. |
BlueprintServiceName |
No | agenticblueprint |
Downstream API name for the Blueprint (agent application) token-exchange step. Used by GetAgenticApplicationTokenAsync; must be configured app-only with the api://AzureAdTokenExchange/.default scope on the sidecar. |
Scopes |
No | — | Scope overrides forwarded as optionsOverride.Scopes. |
SidecarBaseUrl |
No | http://localhost:5178 |
Sidecar endpoint. Resolution: SIDECAR_URL env var > this > default. The resolved host must be loopback/private unless BypassLocalNetworkRestriction is set. |
BypassLocalNetworkRestriction |
No | false |
UNSAFE. Disables the loopback/private-address SSRF safety check. Only enable for a carefully validated private-network configuration (see above). |
RequestTimeout |
No | 00:00:30 |
Per-attempt HTTP timeout for sidecar calls. |
RetryCount |
No | 3 |
Retry attempts for transient failures (HTTP 408/429/5xx, network errors, timeouts) using exponential backoff. 0 disables retries. |
ClientId / TenantId |
No | — | Inherited from ConnectionSettingsBase; surfaced via ConnectionSettings. Not used for token acquisition (the sidecar owns the credential). |
Code-first DI registration
builder.Services.AddSidecarConnections(builder.Configuration);
Health check
Register the sidecar reachability probe with the ASP.NET Core health-check pipeline:
builder.Services.AddHealthChecks().AddSidecarHealthCheck();
...
app.MapHealthChecks("/health");
Startup probe (optional)
Probe the sidecar once at startup. By default an unreachable sidecar logs a warning and startup continues; pass failOnUnreachable: true to fail fast instead:
builder.Services.AddSidecarStartupProbe(failOnUnreachable: false);
Sidecar-side requirements
The sidecar must declare matching downstream APIs:
- The connection's
ServiceName(e.g.botframework) with the appropriate scope. - A Blueprint downstream API named by
BlueprintServiceName(defaultagenticblueprint), configured app-only (RequestAppToken: true) with theapi://AzureAdTokenExchange/.defaultscope. This is whatGetAgenticApplicationTokenAsynccalls.
See the runnable end-to-end example in src/samples/Authorization/SidecarAuth.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Azure.Core (>= 1.50.0)
- Microsoft.Agents.Authentication (>= 1.7.123)
- Microsoft.Extensions.Configuration (>= 10.0.7)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.7)
- Microsoft.Extensions.DependencyInjection (>= 10.0.7)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.7)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Http (>= 10.0.7)
- Microsoft.Extensions.Logging (>= 10.0.7)
- System.IdentityModel.Tokens.Jwt (>= 8.15.0)
-
net8.0
- Azure.Core (>= 1.50.0)
- Microsoft.Agents.Authentication (>= 1.7.123)
- Microsoft.Extensions.Configuration (>= 10.0.7)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.7)
- Microsoft.Extensions.DependencyInjection (>= 10.0.7)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.7)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Http (>= 10.0.7)
- Microsoft.Extensions.Logging (>= 10.0.7)
- System.IdentityModel.Tokens.Jwt (>= 8.15.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.8.3-beta | 45 | 7/24/2026 |
| 1.7.123 | 0 | 7/28/2026 |
| 1.7.119-beta | 46 | 7/22/2026 |
| 1.7.111-beta | 45 | 7/21/2026 |
| 1.7.108-beta | 48 | 7/19/2026 |
| 1.7.88-beta | 45 | 7/16/2026 |
| 1.7.79-beta | 50 | 7/15/2026 |
| 1.7.70-beta | 52 | 7/15/2026 |
| 1.7.25-beta | 58 | 7/3/2026 |
| 1.7.20-beta | 58 | 6/30/2026 |
| 1.7.16-beta | 63 | 6/27/2026 |
| 1.7.12-beta | 70 | 6/26/2026 |