Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
407 changes: 407 additions & 0 deletions .github/agents/django.agent.md

Large diffs are not rendered by default.

407 changes: 407 additions & 0 deletions django.agent.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.418",
"version": "10.0.101",
"rollForward": "latestFeature"
}
}
34 changes: 34 additions & 0 deletions newjson.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/10c419d4-4a50-45b2-aa4e-919fb84df24f/",
"iat": 1772116820,
"nbf": 1772116820,
"exp": 1772120720,
"aio": "k2ZgYNB+d4klYinL6VXezG8Kv0XOv6CfvZtv7csMlcCaaNU/3xIA",
"app_displayname": "agent identity1",
"appid": "ab18ca07-d139-4840-8b3b-4be9610c6ed5",
"appidacr": "2",
"idp": "https://sts.windows.net/10c419d4-4a50-45b2-aa4e-919fb84df24f/",
"idtyp": "app",
"oid": "ab18ca07-d139-4840-8b3b-4be9610c6ed5",
"rh": "1.AXEB1BnEEFBKskWqTpGfuE3yTwMAAAAAAAAAwAAAAAAAAAAAAABxAQ.",
"roles": [
"Application.Read.All"
],
"sub": "ab18ca07-d139-4840-8b3b-4be9610c6ed5",
"tenant_region_scope": "NA",
"tid": "10c419d4-4a50-45b2-aa4e-919fb84df24f",
"uti": "IYGgzr8M10aNw3nANQ54AA",
"ver": "1.0",
"wids": [
"0997a1d0-0d1d-4acb-b408-d5ca73121e90"
],
"xms_act_fct": "3 11 9",
"xms_ftd": "sw2pKG6aFqnm6r73WSeCHfTFQuXdVSMGGhwt6ZXNZc0BdXNlYXN0LWRzbXM",
"xms_idrel": "7 24",
"xms_par_app_azp": "aab5089d-e764-47e3-9f28-cc11c2513821",
"xms_rd": "0.42LjYBJi-sgkJMLBLiSwXPdScKJQr_NWO_4eqyYDb6Aop5BACO8aMca9x723774btjW2UgsoyiEkwMwAAQegNFCUW0jg2WZn59bGuydzGyIX-4RWM0jxcXAJcRmamxsZGppZGFoCAA",
"xms_sub_fct": "3 11 9",
"xms_tcdt": 1753717349,
"xms_tnt_fct": "3 12"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Identity.Client
{
/// <summary>
/// Builder for acquiring a user-delegated token for an agent identity, acting on behalf of a specified user.
/// Use <see cref="IConfidentialClientApplication.AcquireTokenForAgentOnBehalfOfUser(string, IEnumerable{string}, string)"/>
/// to create this builder.
/// </summary>
/// <remarks>
/// This flow internally:
/// <list type="number">
/// <item>Obtains an FMI credential (FIC) from the token exchange endpoint using the CCA's credential.</item>
/// <item>Obtains a User Federated Identity Credential (User FIC) for the agent.</item>
/// <item>Exchanges the User FIC for a user-delegated token via the <c>user_fic</c> grant type.</item>
/// </list>
/// After a successful acquisition, you can use <see cref="IClientApplicationBase.AcquireTokenSilent(IEnumerable{string}, IAccount)"/>
/// with the returned account for subsequent cached token lookups.
/// </remarks>
#if !SUPPORTS_CONFIDENTIAL_CLIENT
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
#endif
public sealed class AcquireTokenForAgentOnBehalfOfUserParameterBuilder
{
private readonly ConfidentialClientApplication _app;
private readonly string _agentId;
private readonly IEnumerable<string> _scopes;
private readonly string _userPrincipalName;
private bool _forceRefresh;
private Guid? _correlationId;

internal AcquireTokenForAgentOnBehalfOfUserParameterBuilder(
ConfidentialClientApplication app,
string agentId,
IEnumerable<string> scopes,
string userPrincipalName)
{
_app = app ?? throw new ArgumentNullException(nameof(app));
_agentId = agentId ?? throw new ArgumentNullException(nameof(agentId));
_scopes = scopes ?? throw new ArgumentNullException(nameof(scopes));
_userPrincipalName = userPrincipalName ?? throw new ArgumentNullException(nameof(userPrincipalName));
}

/// <summary>
/// Forces MSAL to refresh the token from the identity provider, bypassing the cache.
/// </summary>
/// <param name="forceRefresh">If <c>true</c>, ignore any cached tokens and request a new token.</param>
/// <returns>The builder, for fluent chaining.</returns>
public AcquireTokenForAgentOnBehalfOfUserParameterBuilder WithForceRefresh(bool forceRefresh)
{
_forceRefresh = forceRefresh;
return this;
}

/// <summary>
/// Sets a correlation ID for telemetry and diagnostics.
/// </summary>
/// <param name="correlationId">A GUID to correlate requests across services.</param>
/// <returns>The builder, for fluent chaining.</returns>
public AcquireTokenForAgentOnBehalfOfUserParameterBuilder WithCorrelationId(Guid correlationId)
{
_correlationId = correlationId;
return this;
}

/// <summary>
/// Executes the token acquisition asynchronously.
/// </summary>
/// <param name="cancellationToken">Cancellation token to cancel the operation.</param>
/// <returns>An <see cref="AuthenticationResult"/> containing the requested user-delegated token.</returns>
public Task<AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken = default)
{
return _app.ExecuteAgentOnBehalfOfUserAsync(
_agentId, _scopes, _userPrincipalName, _forceRefresh, _correlationId, cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Identity.Client
{
/// <summary>
/// Builder for acquiring an app-only token for an agent identity via a
/// <see cref="IConfidentialClientApplication"/>.
/// Use <see cref="IConfidentialClientApplication.AcquireTokenForAgent(string, IEnumerable{string})"/>
/// to create this builder.
/// </summary>
/// <remarks>
/// This flow internally:
/// <list type="number">
/// <item>Obtains an FMI credential (FIC) from the token exchange endpoint using the CCA's credential.</item>
/// <item>Uses the FIC as a client assertion to acquire a token for the requested scopes.</item>
/// </list>
/// </remarks>
#if !SUPPORTS_CONFIDENTIAL_CLIENT
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
#endif
public sealed class AcquireTokenForAgentParameterBuilder
{
private readonly ConfidentialClientApplication _app;
private readonly string _agentId;
private readonly IEnumerable<string> _scopes;
private bool _forceRefresh;
private Guid? _correlationId;

internal AcquireTokenForAgentParameterBuilder(
ConfidentialClientApplication app, string agentId, IEnumerable<string> scopes)
{
_app = app ?? throw new ArgumentNullException(nameof(app));
_agentId = agentId ?? throw new ArgumentNullException(nameof(agentId));
_scopes = scopes ?? throw new ArgumentNullException(nameof(scopes));
}

/// <summary>
/// Forces MSAL to refresh the token from the identity provider, bypassing the cache.
/// </summary>
/// <param name="forceRefresh">If <c>true</c>, ignore any cached tokens and request a new token.</param>
/// <returns>The builder, for fluent chaining.</returns>
public AcquireTokenForAgentParameterBuilder WithForceRefresh(bool forceRefresh)
{
_forceRefresh = forceRefresh;
return this;
}

/// <summary>
/// Sets a correlation ID for telemetry and diagnostics.
/// </summary>
/// <param name="correlationId">A GUID to correlate requests across services.</param>
/// <returns>The builder, for fluent chaining.</returns>
public AcquireTokenForAgentParameterBuilder WithCorrelationId(Guid correlationId)
{
_correlationId = correlationId;
return this;
}

/// <summary>
/// Executes the token acquisition asynchronously.
/// </summary>
/// <param name="cancellationToken">Cancellation token to cancel the operation.</param>
/// <returns>An <see cref="AuthenticationResult"/> containing the requested token.</returns>
public Task<AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken = default)
{
return _app.ExecuteAgentTokenAcquisitionAsync(
_agentId, _scopes, _forceRefresh, _correlationId, cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ public string ClientVersion
public bool IsPublicClient => !IsConfidentialClient && !IsManagedIdentity;
public string CertificateIdToAssociateWithToken { get; set; }

public string FederatedCredentialAudience { get; internal set; } = "api://AzureADTokenExchange/.default";

public Func<AppTokenProviderParameters, Task<AppTokenProviderResult>> AppTokenProvider;

internal IRetryPolicyFactory RetryPolicyFactory { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,23 @@ internal ConfidentialClientApplicationBuilder WithAppTokenCacheInternalForTest(I
return this;
}

/// <summary>
/// Sets the audience URL used when acquiring Federated Identity Credentials (FIC) for agentic flows.
/// Defaults to <c>api://AzureADTokenExchange/.default</c>. Override for airgapped or sovereign clouds.
/// </summary>
/// <param name="audience">The FIC audience URL.</param>
/// <returns>The builder to chain the .With methods.</returns>
public ConfidentialClientApplicationBuilder WithFederatedCredentialAudience(string audience)
{
if (string.IsNullOrWhiteSpace(audience))
{
throw new ArgumentNullException(nameof(audience));
}

Config.FederatedCredentialAudience = audience;
return this;
}

/// <inheritdoc/>
internal override void Validate()
{
Expand Down
Loading
Loading