Skip to content

[Do not review] Agent ID support through minimal changes#6008

Closed
Avery-Dunn wants to merge 5 commits into
mainfrom
avdunn/agent-id-support-alt
Closed

[Do not review] Agent ID support through minimal changes#6008
Avery-Dunn wants to merge 5 commits into
mainfrom
avdunn/agent-id-support-alt

Conversation

@Avery-Dunn

@Avery-Dunn Avery-Dunn commented May 14, 2026

Copy link
Copy Markdown
Contributor

Not yet ready for review, just exploring potential alternatives to: #5883

Currently adds:

  • WithClientIdOverride: a new request level parameter, to help test whether using the correct client ID in the cache key is enough to avoid the agent ID flow's cache collision risks
    • AgentIdentityCacheIsolationTests: new unit test class covering:
      • TwoUsers_SameAgent_NoCacheCollision_Test: Two different users through the same agent have distinct cache entries (different HomeAccountId), silent calls return the correct user's token
      • TwoAgents_SameUser_NoCacheCollision_Test: Same user through two different agents has distinct cache entries (different ClientId in key), silent calls return the correct agent's token
      • AgentUserToken_DoesNotCollide_WithBlueprintUserToken_Test: A user token acquired via agent (with override) doesn't collide with the same user+scope acquired directly by the blueprint (without override)
    • Agentic: Extra integration tests covering:
      • SingleCca_AgentUserIdentity_WithCacheHit_Test: Full 3-leg flow works end-to-end, all legs cache correctly, silent works, force-refresh works
      • SingleCca_AgentUserIdentity_AppTokenCacheIsolation_Test: Leg 1 and Leg 2 target the same scope but produce different tokens in different cache partitions

Copilot AI review requested due to automatic review settings May 14, 2026 16:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR explores a minimal agent identity approach by adding a per-request client ID override that affects token requests and cache partitioning, plus integration coverage for single-CCA agent identity flows.

Changes:

  • Adds ClientIdOverride plumbing through common request parameters, token requests, cache saves/lookups, and app-token cache keys.
  • Exposes WithClientIdOverride on confidential-client token builders and silent acquisition builders.
  • Adds integration tests for single-CCA agent identity cache behavior and updates public API manifests.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/Agentic.cs Adds integration tests for single-CCA agent identity flows using client ID override.
src/client/Microsoft.Identity.Client/TokenCache.ITokenCacheInternal.cs Uses effective client ID for token save/filter/account lookup paths.
src/client/Microsoft.Identity.Client/TokenCache.cs Uses effective client ID when deleting overlapping access tokens and matching RTs to accounts.
src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt Adds public API entries for the new override methods.
src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt Adds public API entries for the new override methods.
src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt Adds mobile public API entry for silent override.
src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt Adds mobile public API entry for silent override.
src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt Adds public API entries for the new override methods.
src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt Adds public API entries for the new override methods.
src/client/Microsoft.Identity.Client/OAuth2/TokenClient.cs Sends effective client ID in token request body.
src/client/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs Adds effective client ID request property.
src/client/Microsoft.Identity.Client/Cache/CacheKeyFactory.cs Uses effective client ID for app-token cache keys.
src/client/Microsoft.Identity.Client/ApiConfig/Parameters/AcquireTokenCommonParameters.cs Adds common client ID override storage.
src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenSilentParameterBuilder.cs Adds silent-acquisition override API.
src/client/Microsoft.Identity.Client/ApiConfig/AbstractConfidentialClientAcquireTokenParameterBuilder.cs Adds confidential-client override API.

@@ -3,3 +3,4 @@ Microsoft.Identity.Client.AuthScheme.IAuthenticationOperation3.AfterCredentialEv
Microsoft.Identity.Client.AuthScheme.CredentialEvaluationContext
Microsoft.Identity.Client.AuthScheme.CredentialEvaluationContext.CredentialEvaluationContext(System.Security.Cryptography.X509Certificates.X509Certificate2 mtlsCertificate) -> void
Microsoft.Identity.Client.AuthScheme.CredentialEvaluationContext.MtlsCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
@@ -3,3 +3,4 @@ Microsoft.Identity.Client.AuthScheme.IAuthenticationOperation3.AfterCredentialEv
Microsoft.Identity.Client.AuthScheme.CredentialEvaluationContext
Microsoft.Identity.Client.AuthScheme.CredentialEvaluationContext.CredentialEvaluationContext(System.Security.Cryptography.X509Certificates.X509Certificate2 mtlsCertificate) -> void
Microsoft.Identity.Client.AuthScheme.CredentialEvaluationContext.MtlsCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
public T WithClientIdOverride(string clientId)
{
ValidateUseOfExperimentalFeature();
CommonParameters.ClientIdOverride = clientId ?? throw new ArgumentNullException(nameof(clientId));
"WithClientIdOverride is only supported on confidential client applications.");
}

CommonParameters.ClientIdOverride = clientId ?? throw new ArgumentNullException(nameof(clientId));
msalIdTokenCacheItem = new MsalIdTokenCacheItem(
instanceDiscoveryMetadata.PreferredCache,
requestParams.AppConfig.ClientId,
requestParams.EffectiveClientId,
Comment on lines 99 to +101
msalRefreshTokenCacheItem = new MsalRefreshTokenCacheItem(
instanceDiscoveryMetadata.PreferredCache,
requestParams.AppConfig.ClientId,
requestParams.EffectiveClientId,
Comment on lines 994 to +997
if (filterByClientId)
{
refreshTokenCacheItems.FilterWithLogging(item =>
string.Equals(item.ClientId, ClientId, StringComparison.OrdinalIgnoreCase),
string.Equals(item.ClientId, requestParameters.EffectiveClientId, StringComparison.OrdinalIgnoreCase),
Avery-Dunn and others added 3 commits May 14, 2026 09:54
The net8.0-ios and net8.0-android PublicAPI.Unshipped.txt files were missing
the declaration for AbstractConfidentialClientAcquireTokenParameterBuilder<T>.WithClientIdOverride,
causing build failures in CI (LibsAndSamples.sln).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 14, 2026 17:38
string t1Token = leg1Result.AccessToken;
var leg2Result = await cca
.AcquireTokenForClient([TokenExchangeUrl])
.WithClientIdOverride(AgentIdentity)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this rate, we will move everything to the request. That's the ADAL way. Let's think more about an abstraction.

var leg2Result = await cca
.AcquireTokenForClient([TokenExchangeUrl])
.WithClientIdOverride(AgentIdentity)
.OnBeforeTokenRequest(data =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could have used WithClientAssertion ? The problem with this approach is the expiration of the t1token

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants