Skip to content

[BREAKING] Python: Require explicit AG-UI authorization scope - #9413

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 4 commits into
microsoft:mainfrom
eavanvalkenburg:fix-ag-ui-approval-isolation
Oct 16, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 4 commits into
microsoft:mainfrom
eavanvalkenburg:fix-ag-ui-approval-isolation

Conversation

@eavanvalkenburg

@eavanvalkenburg Eduard van Valkenburg (eavanvalkenburg) commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

AG-UI Thread ids are client-owned protocol correlation values, not authorization boundaries. FastAPI dependencies could authenticate a request while snapshots, internal sessions, workflow continuations, and server-held approval state remained unscoped unless an application separately configured snapshot_scope_resolver.

Make endpoint ownership explicit and give FastAPI applications a direct way to derive the scope from authenticated request context. This prevents authentication from being mistaken for isolation while retaining an explicit local/single-user mode.

Description & Review Guide

  • What are the major changes?
    • Add the public AuthorizationScopeResolver type and authorization_scope_resolver endpoint option. FastAPI invokes the resolver as a dependency, so it can consume Depends, Security, headers, cookies, or Request and return a stable non-empty scope. Async resolvers and awaitable results are both supported.
    • Require every endpoint registration to choose exactly one ownership mode: authorization_scope_resolver, the compatible snapshot_scope_resolver, or explicit single_user=True.
    • Feed the resolved scope through the existing snapshot, internal session, workflow/checkpoint, detached-run, and approval-state boundaries. Invalid configured scopes fail before the runner or protected state is accessed.
    • Give each single-user endpoint registration its own opaque scope so equal route paths in separate applications cannot collide within a process.
    • Update public exports, the function-loop authorization contract, documentation, examples, and endpoint regressions. Local examples declare single-user intent and identify the production migration to an authenticated resolver.
  • What is the impact of these changes?
    • Breaking: endpoint registrations that previously omitted a resolver must now add single_user=True for genuinely single-user use or provide authorization_scope_resolver for shared applications.
    • Existing snapshot_scope_resolver integrations remain supported and retain their current scope values.
    • There is no AG-UI wire-protocol or client-side change. The new parameters are appended to preserve the existing positional parameter order.
    • single_user=True assigns an opaque scope for the lifetime of one endpoint registration. Applications that need durable scope continuity across process restarts or shared storage must provide an explicit resolver.
  • What do you want reviewers to focus on?
    • The explicit-mode API and migration ergonomics, especially whether authorization_scope_resolver composes naturally with existing FastAPI authentication dependencies.
    • The compatibility boundary for snapshot_scope_resolver and single_user=True.
    • Scope resolution occurring before streaming or detached execution begins.

Related Issue

N/A - private security remediation tracked through the restricted Microsoft security-response process. No competing public pull request was found.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: The API design, implementation, tests, documentation, samples, and this PR description were prepared with GitHub Copilot and reviewed by the author.

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 PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after a language prefix) — a workflow keeps the label and title prefix in sync automatically.

Copilot AI balanced review requested due to automatic review settings October 15, 2026 12:08
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible labels Oct 15, 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.

🟡 Changes recommended

The public resolver export is missing from the typing stub, and remaining README registrations omit the required ownership mode.

2 open findings
What changed in this PR

Makes authorization ownership explicit for Python AG-UI endpoints, separating authentication from server-side state isolation.

Changes:

  • Adds a FastAPI authorization-scope resolver and requires exactly one ownership mode.
  • Passes resolved scopes through existing state-isolation boundaries.
  • Updates exports, documentation, examples, and regression tests.
File Description
python/​samples/​05-end-to-end/​ag_ui_workflow_handoff/​backend/​server.py Declares local single-user mode.
python/​packages/​core/​agent_framework/​ag_ui/​__init__.py Exposes the resolver type.
python/​packages/​ag-ui/​tests/​ag_ui/​test_public_exports.py Checks runtime resolver export.
python/​packages/​ag-ui/​tests/​ag_ui/​test_multi_turn.py Updates endpoint ownership configuration.
python/​packages/​ag-ui/​tests/​ag_ui/​test_http_round_trip.py Updates endpoint ownership configuration.
python/​packages/​ag-ui/​tests/​ag_ui/​test_handoff_replay.py Declares single-user test mode.
python/​packages/​ag-ui/​tests/​ag_ui/​test_endpoint.py Tests ownership validation, dependencies, and approval isolation.
python/​packages/​ag-ui/​tests/​ag_ui/​conftest.py Updates shared endpoint fixtures.
python/​packages/​ag-ui/​README.md Documents authorization modes and migration.
python/​packages/​ag-ui/​getting_started/​server.py Derives scope through API-key validation.
python/​packages/​ag-ui/​AGENTS.md Documents the authorization contract.
python/​packages/​ag-ui/​agent_framework_ag_ui/​_endpoint.py Implements explicit modes and dependency-based scoping.
python/​packages/​ag-ui/​agent_framework_ag_ui/​__init__.py Exports the resolver type.
python/​packages/​ag-ui/​agent_framework_ag_ui_examples/​server/​main.py Defaults local examples to single-user mode.
python/​packages/​ag-ui/​agent_framework_ag_ui_examples/​server/​api/​backend_tool_rendering.py Declares local single-user mode.
docs/​specs/​004-python-function-calling-loop.md Specifies explicit approval ownership requirements.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread python/packages/core/agent_framework/ag_ui/__init__.py
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py

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

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): 0594b266b8b5
Model: gpt-5.6-sol

Overview

The PR makes endpoint ownership explicit and consistently propagates the resolved scope through snapshots, sessions, workflows, detached-run admission, and approval state, with strong fail-closed tests for invalid resolver values. Three compatibility and isolation gaps remain: path-only single-user scopes can collide across registrations, one resolver shape permitted by the public type is rejected at runtime, and the core facade's type stub omits the new export. These are bounded but concrete failures that should be corrected before release.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
3 verified findings remained after source verification (3 medium) across 2 files. Details are attached to the affected lines below.

Affected areas: python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py, python/packages/core/agent_framework/ag_ui/__init__.py

Comment thread python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py Outdated
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py
Comment thread python/packages/core/agent_framework/ag_ui/__init__.py

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

MAF Automated Review — Iteration 2

Result: No findings
Scope: 2 net-new commit(s): 633cdfc2fedc, 9b7e6f13a194
Model: gpt-5.6-sol

Overview

This incremental update closes the three prior review gaps by assigning an opaque UUID-backed scope per single-user endpoint registration, awaiting awaitable results from synchronous FastAPI dependencies, and synchronizing the typed public facade. Registration-mode validation, fail-closed scope checks, and focused isolation tests constrain the changed behavior. No new Critical, High, or Medium issue is supported by a changed line in the authoritative diff.

Reviewed the supplied incremental change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.

Comment thread python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py
Merged via the queue into microsoft:main with commit 9a1d66b Oct 16, 2026
49 checks passed
@eavanvalkenburg
Eduard van Valkenburg (eavanvalkenburg) deleted the fix-ag-ui-approval-isolation branch October 16, 2026 03:32

This branch was successfully deployed

1 active deployment
github-app-auth — 286a28e8 Deployed Oct 15, 2026 by eavanvalkenburg via add_label #25464
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants