From 67aed54d9e0abc2f804591a74356ba2468766e62 Mon Sep 17 00:00:00 2001 From: eavanvalkenburg Date: Tue, 15 Sep 2026 16:14:13 +0200 Subject: [PATCH] Python: Clarify MCP annotation override scope --- python/packages/core/agent_framework/security.py | 14 +++++++++++--- .../02-agents/security/FIDES_DEVELOPER_GUIDE.md | 6 ++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/python/packages/core/agent_framework/security.py b/python/packages/core/agent_framework/security.py index 9278ff3b292..12e0a597e00 100644 --- a/python/packages/core/agent_framework/security.py +++ b/python/packages/core/agent_framework/security.py @@ -4077,7 +4077,10 @@ async def apply_mcp_security_labels( annotation_overrides: Optional per-tool-name overrides. Keys are *remote* MCP tool names (as the server exposes them). Values are ``(IntegrityLabel, ConfidentialityLabel | None)`` tuples that - replace the annotation-derived labels entirely. + replace the annotation-derived labels entirely. Overrides apply + only to the supplied ``mcp_tool``; the mapping itself is not bound + to a server identity. Reuse it for another connection only after + independently authorizing that policy for the other server's tools. mark_write_tools_as_sinks: When ``True`` (default), apply the annotation-derived ``max_allowed_confidentiality=PUBLIC`` cap. trust_server_ifc: Whether complete, valid server ``_meta.ifc`` labels @@ -4348,7 +4351,9 @@ class SecureMCPToolProxy: description: Tool description for the internal tool. default_integrity: Default integrity for tools without annotations. annotation_overrides: Per-tool-name label overrides (keyed by remote - MCP tool name). + MCP tool name), applied only to this proxy's MCP connection. + The mapping is not bound to a server identity; reuse it for another + connection only after independently authorizing that policy there. mark_write_tools_as_sinks: Whether to apply the annotation-derived PUBLIC confidentiality cap. trust_server_ifc: Whether complete, valid server ``_meta.ifc`` labels @@ -4387,7 +4392,10 @@ def __init__( description: Tool description for the internal tool. default_integrity: Default integrity for tools without annotations. Defaults to ``IntegrityLabel.UNTRUSTED``. - annotation_overrides: Per-tool-name label overrides keyed by remote MCP tool name. + annotation_overrides: Per-tool-name label overrides keyed by remote MCP tool name, + applied only to this proxy's MCP connection. The mapping is not bound to a + server identity; reuse it for another connection only after independently + authorizing that policy there. mark_write_tools_as_sinks: Whether to apply the annotation-derived PUBLIC confidentiality cap. Defaults to ``True``. trust_server_ifc: Whether complete, valid server ``_meta.ifc`` diff --git a/python/samples/02-agents/security/FIDES_DEVELOPER_GUIDE.md b/python/samples/02-agents/security/FIDES_DEVELOPER_GUIDE.md index 44f8eefee0f..5313d2f6b9c 100644 --- a/python/samples/02-agents/security/FIDES_DEVELOPER_GUIDE.md +++ b/python/samples/02-agents/security/FIDES_DEVELOPER_GUIDE.md @@ -493,6 +493,12 @@ ToolAnnotations authoritative: `readOnlyHint` and `openWorldHint` remain restric secure_mcp = SecureMCPToolProxy(url="https://trusted.example.com/mcp/", trust_server_ifc=True) ``` +`annotation_overrides` supplies explicit local policy keyed by remote MCP tool name. It applies only to the +`MCPTool` passed to `apply_mcp_security_labels`, or the connection wrapped by `SecureMCPToolProxy`; the mapping +itself is not bound to a server identity. Reusing a mapping for another connection applies its overrides to +matching tool names on that connection. Independently authorize the policy for each server's tools before +reusing it; a shared tool name does not establish shared trust. + #### Operational checklist 1. Prefer `async with SecureMCPToolProxy(...)` so connection and label application happen together.