Skip to content

Python: [BREAKING] Reject caller-supplied tool execution context in Responses requests - #9661

Open
Darren Cohen (dargilco) wants to merge 7 commits into
microsoft:mainfrom
dargilco:dargilco/foundry-hosting-reject-caller-tool-context
Open

Darren Cohen (dargilco) wants to merge 7 commits into
microsoft:mainfrom
dargilco:dargilco/foundry-hosting-reject-caller-tool-context

Conversation

@dargilco

@dargilco Darren Cohen (dargilco) commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

ResponsesHostServer converts caller-supplied Responses request fields into Agent Framework run options. The
additional_function_arguments option was not treated as host-controlled, so a caller could supply it as a top-level
field or inside extra_body. It was merged over the developer-configured default_options and became
FunctionInvocationContext.kwargs for every tool call. Tools and skill resources that read hidden runtime context
(for example a tenant or user identifier) could therefore receive caller-chosen values instead of the host's trusted
ones. This also applied when a request resumed a pending tool approval.

The Invocations endpoint already treats this field as agent-controlled. This change applies the same boundary to
the Responses endpoint.

Description & Review Guide

  • What are the major changes?
    • response_run_options in agent_framework_foundry_hosting/_request.py now raises a ValueError when a request
      contains additional_function_arguments at the top level or inside extra_body. The existing request-preparation
      error handling turns this into a failed response that names the field, before any agent or tool runs. Presence
      is rejected even when the value is null.
    • The field is deliberately not added to _HOST_CONTROLLED_FIELDS, so a developer prepare_options hook can
      still supply trusted values (for example derived from request.scope), as can Agent(default_options=...).
    • Added unit tests and HTTP-level tests that use a real Agent, function-invocation loop, and tool. They cover
      the baseline, both injection locations in streaming and non-streaming mode, hook-supplied trusted context, and
      approval resume. The approval test shows that a rejected resume neither runs the tool nor consumes the pending
      approval, and that a later legitimate resume runs with the trusted value.
    • Documented the behavior in the foundry_hosting README.
  • What is the impact of these changes?
    • Requests that previously set additional_function_arguments through the Responses endpoint now fail instead of
      overriding tool context. This is a behavior change for any client that relied on it; trusted values should be set
      in agent defaults or a prepare_options hook.
    • Core merge semantics, direct Agent.run(..., function_invocation_kwargs=...), and the Invocations and native
      workflow paths are unchanged.
  • What do you want reviewers to focus on?
    • Whether rejecting (rather than silently dropping) the field is the right behavior, given that other
      host-controlled fields are silently dropped from Responses requests.
    • Whether prepare_options should remain able to set this field.
    • Whether any other HTTP-facing host, such as AG-UI's approval path in ag-ui/agent_framework_ag_ui/_agent_run.py,
      needs the same boundary. That was not changed or verified here.

Related Issue

Coordinating with maintainers; the issue link will be added here.

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: Implementation, tests, README text, and this PR description were drafted 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 any language prefix) — a workflow keeps the label and title prefix in sync automatically.

…quests

ResponsesHostServer now rejects additional_function_arguments supplied at the top level or in extra_body, including on approval resume, so callers cannot replace host-configured tool context. Developer defaults and prepare_options hooks can still supply trusted values.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 24, 2026 00:50
@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 24, 2026
@dargilco
Darren Cohen (dargilco) marked this pull request as ready for review October 24, 2026 00:54

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.

🔵 Needs a closer look

The security boundary governing tool context during approval resumes warrants final maintainer review.

2 open issues
What changed in this PR

This PR strengthens the Foundry Responses endpoint’s trust boundary by rejecting caller-supplied tool execution context while preserving developer-controlled configuration.

Changes:

  • Rejects additional_function_arguments at the request’s top level or inside extra_body, including null values.
  • Adds regression coverage for streaming, trusted hooks, and approval resumes.
  • Documents the breaking behavior and supported ways to supply trusted context.
File Description
python/​packages/​foundry_hosting/​tests/​test_responses.py Adds HTTP-level context-injection and approval-resume tests.
python/​packages/​foundry_hosting/​tests/​test_request.py Tests field rejection and trusted hook configuration.
python/​packages/​foundry_hosting/​README.md Documents the restriction and trusted alternatives.
python/​packages/​foundry_hosting/​agent_framework_foundry_hosting/​_request.py Rejects caller-controlled tool context during option translation.

Review effort: Balanced

Comment thread python/packages/foundry_hosting/tests/test_request.py Outdated
Comment thread python/packages/foundry_hosting/tests/test_responses.py Outdated

@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)): e67aef89e000
Model: gpt-5.6-sol

Overview

The change blocks caller-controlled tool context before option hooks, approval consumption, model calls, and tool execution for regular agents and native workflows, with focused coverage for both request locations, response modes, trusted hooks, and approval resume. The remaining gap is the legacy WorkflowAgent Responses path, which bypasses the new validator and can execute a request that the documented endpoint contract says must fail.

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

Affected areas: python/packages/foundry_hosting/agent_framework_foundry_hosting/_request.py

Comment thread python/packages/foundry_hosting/agent_framework_foundry_hosting/_request.py Outdated
… module

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… requests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rtlib

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ackages' conftest

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch was successfully deployed

1 active deployment
github-app-auth — 1bb4b33c Deployed Oct 24, 2026 by dargilco via add_label #26073
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.

2 participants