Skip to content

.NET: [Experimental] Extend A2A task store with isolation key scoping - #7504

Merged
SergeyMenshykh merged 2 commits into
microsoft:mainfrom
SergeyMenshykh:sergeymenshykh-fix-a2a-task-store-isolation
Aug 5, 2026
Merged

.NET: [Experimental] Extend A2A task store with isolation key scoping#7504
SergeyMenshykh merged 2 commits into
microsoft:mainfrom
SergeyMenshykh:sergeymenshykh-fix-a2a-task-store-isolation

Conversation

@SergeyMenshykh

@SergeyMenshykh SergeyMenshykh commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

The A2A hosting layer applies isolation key scoping to the session store but not the task store. This PR extends the same isolation pattern to cover task operations.

Description & Review Guide

  • What are the major changes?
    • New IsolationKeyScopedTaskStore class that wraps ITaskStore with per-caller key scoping (mirrors IsolationKeyScopedAgentSessionStore).
    • CreateA2AServer automatically wraps the task store when a SessionIsolationKeyProvider is registered.
    • Updated XML doc trust-model remarks to cover both stores.
    • Updated sample comments to reflect the broader isolation scope.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This is not a breaking change.

Copilot AI lite review requested due to automatic review settings August 4, 2026 13:45
@agent-framework-automation agent-framework-automation Bot added the .NET Usage: [Issues, PRs], Target: .Net label Aug 4, 2026
@SergeyMenshykh SergeyMenshykh self-assigned this Aug 4, 2026
@SergeyMenshykh SergeyMenshykh moved this to In Review in Agent Framework Aug 4, 2026
@SergeyMenshykh
SergeyMenshykh marked this pull request as ready for review August 4, 2026 13:47
@SergeyMenshykh SergeyMenshykh changed the title .NET: Add tenant-scoped task store isolation for A2A hosting .NET: Extend A2A task store with isolation key scoping Aug 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds tenant-scoped isolation to A2A task storage, aligning task operations with the existing session-store isolation model to prevent cross-tenant task access in multi-user hosts.

Changes:

  • Introduces IsolationKeyScopedTaskStore to scope task IDs and persisted AgentTask.ContextId by isolation key (and un-scope on reads).
  • Updates A2A server DI wiring to automatically wrap the configured ITaskStore with tenant isolation when building an A2AServer.
  • Adds unit tests plus updates trust-model/sample comments to reflect that both contextId and taskId are untrusted wire identifiers.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
dotnet/src/Microsoft.Agents.AI.Hosting.A2A/IsolationKeyScopedTaskStore.cs New delegating task store that scopes/unscopes IDs and filters list results by tenant isolation key.
dotnet/src/Microsoft.Agents.AI.Hosting.A2A/A2AServerServiceCollectionExtensions.cs Wraps the resolved ITaskStore in IsolationKeyScopedTaskStore and updates trust-model remarks.
dotnet/tests/Microsoft.Agents.AI.Hosting.A2A.UnitTests/IsolationKeyScopedTaskStoreTests.cs New unit tests for task store scoping/unscoping and tenant separation behaviors.
dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.AgentHost/Program.cs Updates sample commentary to clarify sessions and tasks require isolation in production.
dotnet/samples/05-end-to-end/A2AClientServer/A2AServer/Program.cs Updates sample commentary to clarify sessions and tasks require isolation in production.

@SergeyMenshykh
SergeyMenshykh force-pushed the sergeymenshykh-fix-a2a-task-store-isolation branch from 15098e7 to 736fa72 Compare August 4, 2026 13:57

@github-actions github-actions Bot 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.

Automated Code Review

Reviewers: 4 | Confidence: 56%

✓ Security Reliability

Note: every file-read/grep/bash call in this session was denied by the environment, so I could not complete the bounded repo verification pass. Findings below are limited to what is provable from the diff text alone; anything requiring inspection of A2A library types (AgentTask/ListTasksRequest/ListTasksResponse nullability and paging semantics), IsolationKeyScopedAgentSessionStore, or the surrounding A2AServer wiring was omitted rather than speculated on. The isolation scheme itself looks sound from the diff: EscapeIsolationKey escapes both backslash and colon before joining with the '::' delimiter (lines 155-161), so an escaped key can never contain a bare '::' and one tenant's prefix cannot be a prefix of another's — no cross-tenant key-collision path is visible. Scoping is applied consistently to Get/Save/Delete, and clone-rather-than-mutate is used for both AgentTask and ListTasksRequest, which avoids leaking scoped ids back onto the wire. The one reliability concern I can substantiate from the diff is that ListTasksAsync applies isolation filtering AFTER the inner store has already paginated, which can yield short or empty pages for a tenant in a shared store. This does not leak data, so I am not requesting changes.

✓ Test Coverage

The wrapper itself has strong direct unit coverage, but the security-critical automatic DI wiring is untested.

✓ Failure Modes

File-system access was blocked in this session (all view/grep/glob/bash calls were denied), so I could only review the diff text itself and deliberately withheld any finding that would require reading surrounding source (e.g., the session-store wrapper's strict-mode semantics, ITaskStore/AgentTask nullability contracts, or A2AServer's task-store call sites). Within the diff alone, the isolation logic in IsolationKeyScopedTaskStore is internally consistent and matches the assertions in IsolationKeyScopedTaskStoreTests.cs. One operational failure mode is visible purely from the diff: A2AServerServiceCollectionExtensions.cs now unconditionally wraps a user-registered ITaskStore, changing the persisted key layout from taskId to key::taskId and the persisted ContextId to key::ctx. For any existing deployment that already has both a SessionIsolationKeyProvider and a durable task store, previously persisted tasks silently become unreachable (GetTaskAsync returns null, ListTasksAsync filters them out via IsInScope because their ContextId lacks the prefix) rather than surfacing an error — which contradicts the PR's "not a breaking change" checkbox for that configuration. This is a migration/documentation concern rather than a code defect, so I am not requesting changes.

✓ Design Approach

I was unable to complete a verification pass: every file-access tool (bash, view, grep, glob) returned a permission error in this session, so I could not open ITaskStore/AgentTask definitions, the existing IsolationKeyScopedAgentSessionStore, or the surrounding CreateA2AServer code needed to substantiate any design-level concern. Reading the diff alone, the approach mirrors the existing session-store isolation pattern, the ListTasksAsync scope/unscope logic is internally consistent with the tests in the diff (scoped ContextId on write, prefix filter plus unscope on read, non-mutating clone of both AgentTask and ListTasksRequest), and the TotalSize limitation is explicitly documented in the XML remarks. I have no finding that meets the required file:line evidence bar, so I am reporting none rather than speculating.

Suggestions

  • Confirm that strict: isolationKeyProvider != null does not cause task-store operations to throw on non-HTTP or unauthenticated paths where the provider may legitimately return null.

Automated review by SergeyMenshykh's agents

Wrap ITaskStore with IsolationKeyScopedTaskStore when a
SessionIsolationKeyProvider is registered, mirroring the existing
session store isolation pattern. This ensures task operations are
scoped per tenant in multi-user deployments.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: adc30d6c-ce66-40bb-933e-9801c2156cda
@SergeyMenshykh
SergeyMenshykh force-pushed the sergeymenshykh-fix-a2a-task-store-isolation branch from 736fa72 to 6c00d61 Compare August 4, 2026 14:19
@SergeyMenshykh SergeyMenshykh changed the title .NET: Extend A2A task store with isolation key scoping .NET: [Experimental] Extend A2A task store with isolation key scoping Aug 4, 2026
@SergeyMenshykh
SergeyMenshykh added this pull request to the merge queue Aug 5, 2026
Merged via the queue into microsoft:main with commit da05627 Aug 5, 2026
26 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Done in Agent Framework Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Usage: [Issues, PRs], Target: .Net

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants