Skip to content

Python: Harden FIDES security state and policy enforcement - #9652

Draft
Eduard van Valkenburg (eavanvalkenburg) wants to merge 13 commits into
mainfrom
fix-fides-security-hardening
Draft

Eduard van Valkenburg (eavanvalkenburg) wants to merge 13 commits into
mainfrom
fix-fides-security-hardening

Conversation

@eavanvalkenburg

Copy link
Copy Markdown
Member

Motivation & Context

A private security review identified several cases where FIDES could lose or weaken information-flow state across transcript replay, MCP result retention, hidden argument validation, durable serialization, and invalid tool metadata. These gaps could cause policy decisions to use less restrictive integrity or confidentiality information than the data warranted.

This change hardens SecureAgentConfig and the FIDES middleware pipeline while preserving restored session state and approval-resume behavior. Context-provider message labeling remains separate follow-up work because context providers are trusted plugins with an existing documented trust boundary.

Description & Review Guide

  • What are the major changes?
    • Reconstruct missing FIDES state from caller-replayed and history-provider messages, using conservative labels for unstamped assistant/tool data while keeping restored state authoritative.
    • Retain MCP _meta.ifc in an independently bounded security carrier so generic Host-payload budget exhaustion cannot discard the label; malformed or unretainable supplied IFC metadata fails closed.
    • Split hidden-argument handling into policy preflight and post-authorization materialization so expanded values do not reach Pydantic validators or tool bodies before policy permits the call.
    • Serialize opaque FIDES state with ASCII escapes so lone Unicode surrogates round-trip through JSON and MessagePack session stores.
    • Parse FIDES tool metadata centrally and block unknown or mistyped values with an auditable invalid_policy violation.
    • Add regression coverage across core and AG-UI approval/replay paths and update the FIDES guidance.
  • What is the impact of these changes?
    • Transcript replay without persisted FIDES state now restores a conservative cumulative label instead of starting trusted/public.
    • Invalid security metadata that previously warned and continued now blocks execution.
    • Validators no longer run on expanded hidden values for calls rejected by FIDES.
    • Existing restored sessions and AG-UI approval resumes retain their authoritative state and behavior.
    • Non-history context-provider messages remain under the documented trusted-plugin model pending the follow-up design.
  • What do you want reviewers to focus on?
    • The boundary between reconstructing missing replay state and preserving restored session state.
    • Approval binding and argument-materialization ordering, including validator transformations and runtime kwargs.
    • The independent MCP IFC carrier, its size bound, and fail-closed handling.

Related Issue

N/A - security hardening based on a privately reported issue. Per SECURITY.md, vulnerability details are not tracked in a public GitHub issue; maintainer direction was explicitly confirmed before implementation. The context-provider labeling follow-up is tracked separately in #9645 and is intentionally not closed by this PR. No competing open PR 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: GitHub Copilot assisted with the security assessment, implementation, regression tests, documentation updates, and PR description.

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.

Copilot AI balanced review requested due to automatic review settings October 23, 2026 14:15
@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 labels Oct 23, 2026
@github-code-quality

github-code-quality Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: Python

Python / code-coverage/python

main b79c03c fix-fides-security-h... 8b9c068 +/-
92% 92% 0%
View coverage of the 7 most impacted files.
File main b79c03c fix-fides-security-h... 8b9c068 +/-
packages/core/a...amework/_mcp.py 91% 90% -1%
packages/core/a...ork/security.py 90% 90% 0%
packages/ag-ui/...i/_agent_run.py 90% 90% 0%
packages/core/a.../_middleware.py 96% 96% 0%
packages/core/a...ework/_tools.py 95% 95% 0%
packages/core/a...work/_agents.py 95% 95% 0%
packages/ag-ui/...age_adapters.py 93% 94% +1%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.


Updated October 26, 2026 16:04 UTC

Comment thread python/packages/core/agent_framework/_tools.py Fixed

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

Replay reconstruction can miss loaded history and lose identity-scoped restrictions, leaving downstream policy checks weaker than required.

3 open issues
What changed in this PR

This PR hardens Python FIDES information-flow enforcement across transcript replay, MCP results, hidden arguments, and persisted session state. Non-history context-provider labeling remains a separate follow-up.

Changes:

  • Reconstruct missing replay security state while preserving restored labels.
  • Retain MCP security metadata independently and reject invalid tool policies.
  • Defer hidden-value validation until authorization, support surrogate-safe serialization, and add regression tests and guidance.
File Description
python/​samples/​02-agents/​security/​FIDES_DEVELOPER_GUIDE.md Documents replay handling, metadata validation, and authorization ordering.
python/​packages/​core/​tests/​test_security.py Adds policy, replay, serialization, and validator regressions.
python/​packages/​core/​tests/​core/​test_mcp.py Tests security-label retention when payload budgets are exhausted.
python/​packages/​core/​agent_framework/​security.py Implements replay reconstruction, policy parsing, and deferred argument materialization.
python/​packages/​core/​agent_framework/​_tools.py Integrates deferred security argument materialization into invocation.
python/​packages/​core/​agent_framework/​_middleware.py Tracks the active function middleware pipeline.
python/​packages/​core/​agent_framework/​_mcp.py Adds an independently bounded security-metadata carrier.
docs/​features/​FIDES_IMPLEMENTATION_SUMMARY.md Clarifies enforced flows and context-provider trust boundaries.

Review effort: Balanced

Comment thread python/packages/core/agent_framework/security.py Outdated
Comment thread python/packages/core/agent_framework/security.py Outdated
Comment thread python/packages/core/agent_framework/security.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)): 634139edf460
Model: gpt-5.6-sol

Overview

The PR adds conservative replay reconstruction, independently bounded MCP IFC retention, delayed hidden-argument materialization, ASCII-safe durable state, and centralized tool-policy parsing. Its strongest guardrails are fail-closed MCP labeling, identity-bound argument materialization, unconditional ContextVar cleanup, and targeted regression coverage. Two gaps remain: restored sessions stop conservatively labeling newly supplied assistant/tool input, and explicit null enum policies bypass the new invalid-policy path.

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

Affected areas: python/packages/core/agent_framework/security.py

Comment thread python/packages/core/agent_framework/security.py Outdated
Comment thread python/packages/core/agent_framework/security.py Outdated

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.

Comment thread python/packages/core/agent_framework/security.py
Comment thread python/packages/core/agent_framework/security.py Outdated
Comment thread python/packages/core/agent_framework/security.py Outdated
Comment thread python/packages/core/agent_framework/security.py
Comment thread python/packages/core/agent_framework/_agents.py Fixed

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

Unresolved confidentiality downgrades and synthetic-history tainting undermine the intended security and restored-session behavior.

2 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Synthetic skipped tool results incorrectly taint restored sessions

python/​packages/​ag-ui/​agent_framework_ag_ui/​_agent_run.py:3223

When a user abandons an unanswered client-tool call from the backend snapshot, normalization inserts a framework-generated “Tool execution skipped” result without snapshot provenance. FIDES treats that synthetic result as new UNTRUSTED/PRIVATE data, tainting the restored session and blocking unrelated protected tools. Preserve trusted provenance for synthetic results derived from backend-owned calls without trusting actual client-supplied results, and add an abandoned-call continuation regression with FIDES enabled.

4 resolved since last review

Review effort: Balanced

Comment thread python/packages/core/agent_framework/security.py
Comment thread python/packages/core/agent_framework/security.py Outdated
@eavanvalkenburg

Copy link
Copy Markdown
Member Author

Addressed the current-head Copilot review’s previously missed synthetic skipped-result issue in 4b3fd9660. AG-UI now propagates backend-snapshot provenance only to framework-generated skipped results derived from backend-owned calls; real client tool results remain untrusted. Added an abandoned-call continuation regression with FIDES enabled.

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

Cross-cutting security-boundary changes and unresolved label-handling defects require fixes and final security-focused human review.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Exclude unchanged authenticated placeholders from integrity fallback

python/​packages/​core/​agent_framework/​security.py:1147

Replaying an unchanged, authenticated hidden result as ordinary caller input still applies the UNTRUSTED fallback, even with restored session state. This taints an otherwise clean session and blocks unrelated protected tools although the payload remains hidden. Exempt authenticated-placeholder-only messages from the integrity fallback, retain conservative handling for modified or visible data, and add a caller-input regression.

2 resolved since last review

Review effort: Balanced

Comment thread python/packages/core/agent_framework/security.py
@eavanvalkenburg

Copy link
Copy Markdown
Member Author

Addressed the latest Copilot review’s previously missed authenticated-placeholder caller-input issue in a08f596e4. Replay reconstruction now skips the UNTRUSTED fallback only when the message contains authenticated session-owned hidden placeholders and no visible data; modified placeholders and visible/function-call content remain conservative. Added a caller-input regression that preserves TRUSTED/PRIVATE and allows an unrelated protected action.

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

Confirmation-only resumes can persist TRUSTED/PUBLIC without reconstructing snapshot history when FIDES state is missing.

1 open issue
2 resolved since last review

Review effort: Balanced

Comment thread python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py Outdated

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

Hidden values can reach validators before a later policy enforcer rejects the invocation, leaving an unresolved security boundary violation.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread python/packages/core/agent_framework/security.py

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

Unresolved security findings require correction, and the cross-cutting replay and authorization changes warrant final human review.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment thread python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py
Comment thread python/packages/core/agent_framework/security.py

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

Unresolved argument-authority checks allow post-authorization mutations to escape enforcement.

2 open issues
2 resolved since last review

Review effort: Balanced

Comment thread python/packages/core/agent_framework/security.py Outdated
Comment thread python/packages/core/agent_framework/security.py Outdated

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

Unresolved security findings and changes across policy, replay, and approval boundaries require fixes and final human security review.

2 open issues
2 resolved since last review

Review effort: Balanced

Comment thread python/packages/core/agent_framework/security.py
Comment thread python/packages/core/agent_framework/security.py Outdated

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

Cross-package security-state and approval-lifecycle changes require final maintainer security review and confirmation of core and AG-UI regression validation.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

This branch was previously deployed

1 inactive deployment
github-app-auth — 8b9c0689 Deployed Oct 26, 2026 by eavanvalkenburg via add_label #26196
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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