From 5be85e2dcc1cc8fd55e87158a947a40271c96a0b Mon Sep 17 00:00:00 2001 From: westey <164392973+westey-m@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:41:18 +0000 Subject: [PATCH] Python: Add approval reuse considerations --- .../_harness/_tool_approval.py | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/python/packages/core/agent_framework/_harness/_tool_approval.py b/python/packages/core/agent_framework/_harness/_tool_approval.py index 6e33b205149..9bee53322ef 100644 --- a/python/packages/core/agent_framework/_harness/_tool_approval.py +++ b/python/packages/core/agent_framework/_harness/_tool_approval.py @@ -236,6 +236,13 @@ def to_dict(self, *, exclude: set[str] | None = None, exclude_none: bool = True) def create_always_approve_tool_response(request: Content, *, reason: str | None = None) -> Content: """Create an approval response that records a standing rule for the whole tool. + .. warning:: + Standing rules are stored in the supplied :class:`AgentSession` and are + not tied to the agent or tool instance that created the request. Before + reusing the session with a different agent or tool set, especially one + that can load tools from an outside source such as MCP, ensure the rule + is still appropriate for every matching tool name. + Args: request: The ``function_approval_request`` content to approve. @@ -250,7 +257,15 @@ def create_always_approve_tool_response(request: Content, *, reason: str | None def create_always_approve_tool_with_arguments_response(request: Content, *, reason: str | None = None) -> Content: - """Create an approval response that records a standing rule for the tool and exact arguments.""" + """Create an approval response that records a standing rule for the tool and exact arguments. + + .. warning:: + Standing rules are stored in the supplied :class:`AgentSession` and are + not tied to the agent or tool instance that created the request. Before + reusing the session with a different agent or tool set, especially one + that can load tools from an outside source such as MCP, ensure the rule + is still appropriate for every matching tool name and argument set. + """ return _create_always_approve_response(request, ALWAYS_APPROVE_TOOL_WITH_ARGUMENTS, reason=reason) @@ -364,6 +379,19 @@ class ToolApprovalMiddleware(AgentMiddleware): This middleware is opt-in and requires callers to run the agent with an :class:`AgentSession`, because approval rules and queued requests are stored in session state. + + .. warning:: + **Security.** Standing approval rules persist in the supplied session + and are not tied to the agent or tool instance that recorded them. + Reusing the session with a different or rebuilt agent, or with a changed + tool set, can let another tool with the same name match an earlier rule. + This is especially important when tools can come from an outside source + such as MCP. Before passing such a session to the agent, ensure its + standing approvals are still valid for all tools the agent can use. A + changed tool does not always require a new approval. For example, an + upgraded agent may use an improved version of a tool for which the old + approval is still appropriate. The developer must decide whether each + standing approval should carry over to the changed tool. """ def __init__(