Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential - #9779

Merged
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle
Jul 9, 2026
Merged

Make Azure.Identity optional in AzureFoundry via injectable TokenCredential#9779
Amaury Levé (Evangelink) merged 2 commits into
mainfrom
dev/amauryleve/animated-waddle

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9712

Summary

Implements the TokenCredential-injection option from #9712 so that Microsoft.Testing.Extensions.AzureFoundry no longer carries a hard dependency on Azure.Identity (and its heavyweight MSAL graph). API-key users pull zero managed-identity assemblies; Entra ID / managed identity remains fully supported but is now opt-in — the consumer references Azure.Identity themselves and passes a credential.

This reworks the authentication added in #9707. It is not a revert: the managed-identity capability is preserved, only the Azure.Identity reference and the new DefaultAzureCredential() call move out of the package and into the caller (the idiomatic Azure SDK pattern that Azure.AI.OpenAI itself follows).

Changes

  • OpenAIChatClientProvider.cs — removed the static Lazy<DefaultAzureCredential> and using Azure.Identity. Added an optional injected TokenCredential (new constructor overload), an AuthenticationMode of None/ApiKey/TokenCredential, and GetAuthenticationMode(apiKey, credential). IsAvailable now also requires an API key or an injected credential; when neither is present CreateChatClientAsync throws a clear InvalidOperationException.
  • TestApplicationBuilderExtensions.cs — new AddAzureOpenAIChatClientProvider(this ITestApplicationBuilder, TokenCredential) overload (the parameterless API-key/auto-registered overload is kept).
  • .csproj + Directory.Packages.props — dropped Azure.Identity; added Azure.Core (1.44.1, already the transitive floor from Azure.AI.OpenAI) since TokenCredential now appears in the public API.
  • PublicAPI / InternalAPI — declared the new overload and reconciled the internal-API tracking files.
  • Resources — added the NoAuthenticationConfigured string.
  • PACKAGE.md — documented the opt-in Entra ID model.
  • Unit tests — updated/added coverage for API-key, injected-credential, no-auth-throws, precedence, and null-credential cases.

Behavioral change (needs sign-off)

This drops #9707's zero-configDefaultAzureCredential fallback: Entra users now reference Azure.Identity and pass a credential explicitly. This is exactly the dependency-footprint tradeoff #9712 asks to weigh before GA, surfaced here as a concrete diff for the team to review.

// API-key users: no Azure.Identity dependency at allbuilder.AddAzureOpenAIChatClientProvider();// Managed-identity users: reference Azure.Identity and pass the credentialbuilder.AddAzureOpenAIChatClientProvider(newDefaultAzureCredential());

Verification

  • AzureFoundry project builds clean (0 warnings / 0 errors) and unit tests pass (20/20) — verified prior to a local-worktree file-loss incident; the committed content is byte-identical to the verified changes.

Notes

  • xlf not modified: the package is IsShipping=false, and Arcade's Localization.targets only wires XliffTasks for shipping assemblies, so UpdateXlf is unavailable and CI does not validate xlf for this project. Per the repo rule against hand-editing xlf, the .xlf files are left untouched; the loc pipeline will regenerate them when the package flips to shipping.
  • Also worth confirming at GA (per Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA #9712): whether the pinned Azure SDK versions are still current/supported.

…ential
Removes the hard Azure.Identity/MSAL dependency from the core
Microsoft.Testing.Extensions.AzureFoundry package. API-key users no longer
pull the managed-identity graph; Entra ID / managed identity is now opt-in by
referencing Azure.Identity and passing a TokenCredential to
AddAzureOpenAIChatClientProvider.
Fixes#9712
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 9, 2026 12:34
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 12:39
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 9, 2026

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

This PR reworks the Azure OpenAI chat client provider so that it authenticates with an API key by default and only uses Entra ID / managed identity when a TokenCredential is explicitly supplied. This removes the hard dependency on Azure.Identity (and its MSAL graph) from the package, replacing it with a lighter Azure.Core reference and an injectable credential.

Changes:

  • Replaced the implicit DefaultAzureCredential fallback with an optional, injectable TokenCredential, adding a None authentication mode when neither an API key nor a credential is available.
  • Added a new AddAzureOpenAIChatClientProvider(ITestApplicationBuilder, TokenCredential) overload and a new NoAuthenticationConfigured error resource.
  • Swapped the Azure.Identity package reference for Azure.Core, and updated public/internal API baselines, docs, and tests accordingly.
Show a summary per file
FileDescription
OpenAIChatClientProvider.csCore change: injectable credential, None auth mode, API-key-first selection logic, and throw when no auth is configured.
TestApplicationBuilderExtensions.csAdds a credential-accepting overload and updates XML docs.
Resources/ExtensionResources.resxAdds the NoAuthenticationConfigured error message.
PublicAPI/PublicAPI.Unshipped.txtDeclares the new public overload.
PACKAGE.mdDocuments API-key-by-default and opt-in TokenCredential authentication.
Microsoft.Testing.Extensions.AzureFoundry.csprojReplaces Azure.Identity with Azure.Core.
InternalAPI/InternalAPI.Unshipped.txtAdds new enum members and constructor.
InternalAPI/InternalAPI.Shipped.txtRemoves old enum members and updates GetAuthenticationMode signature.
Directory.Packages.propsReplaces the Azure.Identity package version with Azure.Core.
AzureFoundryChatClientProviderTests.csUpdates and adds tests for the new authentication behavior.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

CopilotAI review requested due to automatic review settings July 9, 2026 17:08
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9779

14 changed test methods graded across 1 file (AzureFoundryChatClientProviderTests): 12 A and 2 B. The two B-grade tests each fold mode-selection and client-construction assertions into a single body — splitting each into two focused tests would sharpen intent and make failure messages more precise. All other tests are clean with well-scoped, precise assertions.

GradeTestNotes
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithApiKey_
UsesApiKeyPathAndReturnsClient
Verifies mode selection and client construction together — consider splitting into two focused single-behavior tests.
B (80–89)mod AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithCredentialAndNoApiKey_
UsesCredentialPathAndReturnsClient
Verifies credential mode and client construction in one body — consider splitting for cleaner single-behavior isolation.
A (90–100)new AzureFoundryChatClientProviderTests.
Constructor_
WithNullCredential_
Throws
Concise null-arg guard using ThrowsExactly — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
CreateChatClientAsync_
WithoutApiKeyOrCredential_
Throws
Clean exception test; verifies exact type and message content — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKey_
ReturnsApiKey
Updated to two-parameter signature; equality assertion is complete for this pure function — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithApiKeyAndCredential_
ReturnsApiKey
Tests key-over-credential precedence with precise equality — no issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithCredentialAndNoApiKey_
ReturnsTokenCredential
No issues found.
A (90–100)new AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndCredential_
ReturnsTokenCredential
Empty-string key treated same as null when a credential is present — edge case covered correctly.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithEmptyApiKeyAndNoCredential_
ReturnsNone
Tests empty-string key without credential returns None — edge case properly asserted.
A (90–100)mod AzureFoundryChatClientProviderTests.
GetAuthenticationMode_
WithoutApiKeyOrCredential_
ReturnsNone
Renamed to reflect new None mode; equality assertion is precise — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenDeploymentMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.
A (90–100)new AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithCredential_
ReturnsTrue
New test covers credential injection path; boolean state assertion is clear — no issues.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointAndDeploymentSetWithoutApiKeyOrCredential_
ReturnsFalse
Renamed + inverted to correctly test no-auth unavailability — no issues found.
A (90–100)mod AzureFoundryChatClientProviderTests.
IsAvailable_
WhenEndpointMissing_
ReturnsFalse
Setup now includes API key to reflect new auth requirements — no issues.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 84.2 AIC · ⌖ 10 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI 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.

Review details

  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Medium

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 18:58
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 9, 2026 19:04
@Evangelink
Amaury Levé (Evangelink) merged commit fbbbfb9 into mainJul 9, 2026
54 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/animated-waddle branch July 9, 2026 19:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit Azure.Identity dependency in Microsoft.Testing.Extensions.AzureFoundry before GA

3 participants

@Evangelink@0101