Skip to content

Python: validate local shell approval binding - #8233

Open
Eduard van Valkenburg (eavanvalkenburg) wants to merge 1 commit into
microsoft:mainfrom
eavanvalkenburg:workflow-input-fix
Open

Python: validate local shell approval binding#8233
Eduard van Valkenburg (eavanvalkenburg) wants to merge 1 commit into
microsoft:mainfrom
eavanvalkenburg:workflow-input-fix

Conversation

@eavanvalkenburg

Copy link
Copy Markdown
Member

Motivation & Context

Add end-to-end coverage that verifies a local shell invocation supplied through a labeled variable remains bound to the command reviewed during approval and cannot be replayed across turns or sessions.

Description & Review Guide

  • What are the major changes? Added deterministic LocalShellTool regression coverage for exact approved argv, changed variable resolution, substituted approval fields, and replay isolation.
  • What is the impact of these changes? Test-only coverage; runtime behavior and public APIs are unchanged. The LocalShellTool suite, focused core approval/security regressions, tools syntax checks, and tools test typing pass.
  • What do you want reviewers to focus on? Confirm the scenarios exercise the full function-invocation, approval, variable-expansion, policy, and subprocess boundary without relying on a real shell process.

Related Issue

N/A - no high-confidence overlapping open issue was found.

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 is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • 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 the title prefix in sync automatically.

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

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.

🟢 Approval recommended

The test-only changes comprehensively validate the stated approval-binding scenarios without runtime or API impact.

Pull request overview

Adds deterministic end-to-end regression coverage for secure LocalShellTool approval binding.

Changes:

  • Verifies exact approved argv execution and variable-change rejection.
  • Tests substituted approval fields and replay isolation across turns and sessions.
File summaries
File Description
python/packages/tools/tests/test_local_shell_tool.py Adds mocked subprocess approval-binding security tests.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Balanced

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

@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: No findings
Scope: full PR (1 commit(s)): 94ff9d9be89a
Model: gpt-5.6-sol-fast

Overview

This test-only PR adds end-to-end LocalShellTool coverage across variable expansion, policy approval, immutable pending-request rebinding, subprocess execution, and replay handling. Existing occurrence identity, resolved-argument signatures, session-scoped state, and consume-on-bind behavior provide concrete guardrails, and the new assertions verify that substituted fields cannot alter executed argv. No PR-introduced Critical, High, or Medium defect was established.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.

options: Mapping[str, Any],
**kwargs: Any,
) -> Awaitable[ChatResponse]:
assert not stream

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Seems to me like you can probably get rid of stream? I also don't see _inner_get_response called anywhere directly in the test. Is this an API enforced by BaseChatClient ?

Comment on lines +438 to +443
if mutation == "request_id":
create_process.assert_not_awaited()
else:
assert create_process.await_count == 1
assert create_process.await_args is not None
assert create_process.await_args.args == (_TEST_SHELL, "-c", _APPROVED_COMMAND)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At a glance, it's not entirely obvious to me which code path is the one meant to fail the test. Maybe it would be clearer if we raised something instead? Not sure if that is a common pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants