Skip to content

Python: feat(core): add session-scoped file access isolation - #8542

Open
JHf0912 wants to merge 3 commits into
microsoft:mainfrom
JHf0912:fix/8539-file-access-session-scoped
Open

JHf0912 wants to merge 3 commits into
microsoft:mainfrom
JHf0912:fix/8539-file-access-session-scoped

Conversation

@JHf0912

@JHf0912 JHf0912 commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Problem

create_harness_agent's file_access_store expects a caller-supplied AgentFileStore whose root is already the desired working directory. Unlike FileMemoryProvider, FileAccessProvider provides no session isolation, so hosts that compile the harness agent before a session exists (AG-UI entrypoints, workflow executors restored from checkpoints) cannot give each session an isolated workspace without baking the session id into the path, recreating the agent per session, or mutating private store fields. Sessions therefore share one workspace, or hosts rely on private-API workarounds.

Fixes #8539

Solution

Mirror FileMemoryProvider's scoping model with an opt-in session_scoped mode on FileAccessProvider (plus an optional explicit scope). When enabled, before_run derives a working folder from self.scope or context.session_id via the shared _storage_key_segment derivation under a file-access-specific ~access- prefix, fails closed (ValueError) when neither is available, creates the folder, and all eight tools route store calls through a single _session_path helper; ls/grep treat an empty directory as the session root and grep results stay session-relative. Default mode is unchanged, preserving shared-store semantics and backward compatibility. create_harness_agent exposes it via file_access_session_scoped.

Changes

  • FileAccessProvider: session_scoped/scope params, _resolve_session_key (fail-closed, ~access- prefix), session folder creation in before_run, session-isolation instruction suffix, debug log of the derived folder, and prefixed store paths across all eight tools.
  • create_harness_agent: file_access_session_scoped flag, assembly pass-through, .pyi stub sync, and packages/core/AGENTS.md doc update.
  • Tests: seven provider-level tests (including the COLLIDING_IDENTIFIERS attack-string parametrization, fail-closed coverage, scope override, grep session-relative names, default shared-store regression) and one wiring test.

Testing

  • pytest tests/core/test_harness_file_access.py tests/core/test_harness_file_memory.py tests/core/test_harness_agent.py — all pass; new session-scoped tests were written first (red) and pass with the implementation (green).
  • Full core suite: the only failure is the pre-existing test_feature_stage.py::test_feature_id_allows_lowercase_values, which also fails on a clean checkout of main (verified via stash).
  • ruff check / ruff format clean; pyright reports no new errors in touched files.
  • End-to-end demo: two sessions writing the same file name land in distinct working folders and cannot read each other's content; session-scoped mode without a session id raises ValueError; default mode keeps files at the shared store root.

Notes for Reviewer

  • The storage namespace prefix is ~access- rather than the ~session-/~scope- used by other components, per the core AGENTS.md convention of one ~-prefixed namespace per component.
  • scope is deliberately not exposed on create_harness_agent (mirroring how FileMemoryProvider is wired without scope); callers needing an explicit scope construct the provider directly.
  • This implements the shape proposed in the issue comment; if the core team prefers the file_access_store_factory alternative, the provider-level plumbing is independent of that choice.
  • The instruction suffix added in scoped mode is intentional: the default instructions describe the store as shared, which would mislead the model when isolation is on.

Add an opt-in session_scoped mode (with an optional explicit scope) that
confines file-access tool operations to a working folder derived from the
session id via the shared _storage_key_segment derivation under the
file-access-specific "~access-" prefix, mirroring FileMemoryProvider. The
mode fails closed (ValueError) when neither a scope nor a session id is
available, creates the session folder in before_run, appends a
session-isolation note to the tool instructions, and logs the derived
folder at debug level. All eight tools route store calls through a single
_session_path helper; ls/grep treat an empty directory as the session root
and grep results stay session-relative. Default mode is byte-for-byte
unchanged.

Adds seven regression tests, including the COLLIDING_IDENTIFIERS attack
strings parametrization, fail-closed coverage, scope override, and
shared-store default regression. All harness file-access tests pass; the
only full-suite failure is the pre-existing
test_feature_stage.py::test_feature_id_allows_lowercase_values on main.

Addresses microsoft#8539.
Expose the FileAccessProvider session-scoped mode from
create_harness_agent via a new file_access_session_scoped flag (default
False, preserving shared-store semantics), threaded through
_assemble_context_providers and synchronized across the .pyi stub and the
package AGENTS.md file-access section.

Adds a pass-through regression test. Addresses microsoft#8539.
Copilot AI balanced review requested due to automatic review settings September 19, 2026 08:30
@JHf0912
JHf0912 deployed to github-app-auth September 19, 2026 08:30 — with GitHub Actions Active
@JHf0912
JHf0912 deployed to github-app-auth September 19, 2026 08:30 — with GitHub Actions Active
@JHf0912
JHf0912 deployed to github-app-auth September 19, 2026 08:31 — with GitHub Actions Active
@JHf0912
JHf0912 deployed to github-app-auth September 19, 2026 08:31 — with GitHub Actions Active
@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 Sep 19, 2026
@github-actions github-actions Bot changed the title feat(core): add session-scoped file access isolation Python: feat(core): add session-scoped file access isolation Sep 19, 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.

Copilot review overview

🟡 Changes recommended

Scoped instructions and directory validation are inconsistent with the new API’s documented behavior.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
What changed in this PR

Adds opt-in session-scoped isolation for Python harness file-access tools.

Changes:

  • Derives per-session or explicit-scope workspace paths.
  • Exposes session scoping through create_harness_agent.
  • Adds documentation and isolation tests.
File Description
python/​packages/​core/​agent_framework/​_harness/​_file_access.py Implements scoped file-access routing.
python/​packages/​core/​agent_framework/​_harness/​_agent.py Wires the new harness option.
python/​packages/​core/​agent_framework/​_harness/​_agent.pyi Updates the public signature stub.
python/​packages/​core/​tests/​core/​test_harness_file_access.py Tests isolation and compatibility.
python/​packages/​core/​tests/​core/​test_harness_agent.py Tests harness option wiring.
python/​packages/​core/​AGENTS.md Documents scoped file access.

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

Comment on lines +75 to +78
_SESSION_SCOPED_INSTRUCTIONS_SUFFIX = (
"\n- Your file workspace is isolated to the current session: files written "
"here are not visible to other sessions or agents."
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — addressed in ebbbd6d. The instruction suffix now says the workspace is "isolated to the current session or configured scope: files written here are not visible outside that workspace", which is accurate in both modes. The same workspace-relative wording was also applied to the two docstring locations flagged here (the class docstring now notes the default is shared and scoped mode confines operations to the derived workspace; the session_scoped parameter doc now spells out "per session by default, or shared across sessions when an explicit scope is set").

All harness file-access tests still pass; ruff clean.

…kspace

The session-scoped instruction suffix claimed files are never visible to
other sessions, which is wrong when an explicit scope intentionally shares
a workspace across sessions. Rephrase the suffix, the class docstring, and
the session_scoped parameter docs to describe isolation relative to the
resolved workspace (session or configured scope).

Addresses review feedback on PR microsoft#8542.
@JHf0912
JHf0912 deployed to github-app-auth September 19, 2026 08:44 — with GitHub Actions Active
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.

Python: Harness: session-scoped file_access_store option when session_id is unknown at create_harness_agent time

2 participants