Repository navigation
.NET: Preserve toolbox OAuth consent context - #9565
Roger Barreto (rogerbarreto) merged 3 commits into
Conversation
Bind request consent state across stream advances and disposal. Extract the actual consent URL without bypassing link validation. Refs microsoft#8379
There was a problem hiding this comment.
🟢 Approval recommended
Static review identified no blocking issues in the focused changes or regression coverage; tests were not executed during review.
No open issues 🎉
What changed in this PR
Preserves OAuth consent requests during hosted .NET agent streaming. This addresses missing consent responses from #8379, not callback identity binding.
Changes:
- Bind request-owned consent state during stream advancement and disposal, restoring the previous context afterward.
- Extract consent URLs from structured error details, falling back to the message only when details are absent.
- Add regressions for real MCP tool invocation, concurrent requests, malformed details, and early disposal.
| File | Description |
|---|---|
| dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/OAuthConsentToolInvocationTests.cs | Adds MCP consent propagation and isolation regressions. |
| dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/OAuthConsentPolicyHandlerTests.cs | Tests context preservation during early disposal. |
| dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/McpConsentContext.cs | Clarifies context lifetime documentation. |
| dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/ConsentAwareMcpClientAIFunction.cs | Extracts consent URLs and corrects output-item documentation. |
| dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/AgentFrameworkResponseHandler.cs | Scopes consent context around stream advancement and disposal. |
Review effort: Balanced
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: No findings
Scope: full PR (1 commit(s)): be1d3a22f09d
Model: gpt-5.6-sol
Overview
The change preserves request-owned OAuth consent state across async stream advancement and disposal, restores prior ambient state in finally, and prefers structured MCP error details with a constrained legacy fallback. Concurrent-request, malformed-detail, URL-policy, persistence, and early-disposal tests provide strong coverage, and no publishable Critical, High, or Medium defect remained after reconciliation.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.
Motivation & Context
Hosted agents can lose an OAuth consent request after streaming a tool-call event. When the toolbox returns JSON-RPC
-32006, the consent wrapper no longer sees the request's consent state, so the error reaches the model asError: Function failed.instead of reaching the caller as anoauth_consent_request.Even when the state is available, using the MCP exception's entire formatted message as the consent URL causes the existing URL policy to reject an otherwise valid link.
Description & Review Guide
finally. Read the consent URL from structured error details, with an exact SDK-prefix fallback only when the detail field is absent. Add regressions using the real MCP client and function-execution loop, including concurrent requests, invalid details, and early stream disposal.AIContent.RawRepresentation. Completing OAuth authorization and verifying callback identity binding were not part of that comparison.Related Issue
Refs #8379, specifically the missing consent response reported in this reproduction.
This PR deliberately does not close #8379 because the original report also concerns OAuth callback identity binding, which this change does not establish as fixed. No competing open PR was found. The issue remains in triage without a public implementation-approval label or comment.
AI Assistance
AI assistance details: Copilot assisted with diagnosis, implementation, regression tests, live reproduction, and this PR description.
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after a language prefix) and the workflows keep the label and title prefix in sync automatically.