Skip to content

[dotnet-port-api] Align shell policy allow and deny semantics - #1047

Open
Michelle Clayton (michelle-clayton-work) wants to merge 4 commits into
mainfrom
dotnet-port-api-shellpolicy-deny-first-e4eefad3518aecdc
Open

[dotnet-port-api] Align shell policy allow and deny semantics#1047
Michelle Clayton (michelle-clayton-work) wants to merge 4 commits into
mainfrom
dotnet-port-api-shellpolicy-deny-first-e4eefad3518aecdc

Conversation

@michelle-clayton-work

Copy link
Copy Markdown
Contributor

Summary

Align tool/shelltool with the upstream .NET ShellPolicy behavior from microsoft/agent-framework#6906.

This change makes Go shell policy evaluation deny-first, treats a supplied allow-list as exclusive, distinguishes nil from an empty allow-list, and adds a final PolicyConfig.Custom override callback that only runs after deny/allow-list checks pass. The shell policy tests were updated to cover the new behavior.

Upstream source commit: ccba1fbbef9aff7d6e5435fb74f0cc7789ca5243 (link).

Ported .NET PRs

Breaking Changes

Yes.

Previously, a Go AllowList match short-circuited the deny-list and a supplied empty allow-list behaved like no allow-list. After this change, deny-list matches win first, a non-nil allow-list is exclusive, and an empty allow-list denies every command. This is an intentional beta-stage parity realignment with the upstream .NET shell policy behavior.

Tests and Examples

  • go test ./tool/shelltool
  • go test ./...
  • Added shell policy coverage for deny-first precedence, exclusive allow-list behavior, empty-vs-nil allow-list handling, and PolicyConfig.Custom callback ordering
  • No examples changed; the user-facing change is covered by policy behavior tests

Notes

Generated by .NET to Go API Porting Agent · 773.7 AIC · ⌖ 54 AIC · ⊞ 21.7K ·

Closes #443

Copilot AI lite review requested due to automatic review settings September 9, 2026 20:25
@github-actions github-actions Bot added area:github Changes files in the github area area:tool Changes files in the tool area size:xlarge More than 300 changed lines or 10 files labels Sep 9, 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.

🟡 Changes recommended

The new PolicyConfig.Custom callback currently receives the untrimmed command while deny/allow checks use a trimmed command, creating an inconsistent API surface that should be made consistent.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Aligns the Go tool/shelltool policy evaluation semantics with upstream .NET ShellPolicy (deny-first precedence, exclusive allow-list behavior including nil-vs-empty distinction), and adds CI guardrails to prevent drift in generated agentic workflow lock files.

Changes:

  • Update shell policy evaluation to be deny-first, make a non-nil allow-list exclusive (empty allow-list denies all), and add a post-list Custom override callback.
  • Expand shell policy tests to cover deny/allow precedence, nil-vs-empty allow-list behavior, and custom-callback ordering.
  • Add a GitHub Actions gate to verify agentic workflow lock files are regenerated with a pinned gh-aw version; adjust Dependabot to avoid bumping lock-embedded action pins.
File summaries
File Description
tool/shelltool/shelltool.go Changes policy evaluation semantics (deny-first, exclusive allow-list) and adds PolicyConfig.Custom / Policy.custom callback.
tool/shelltool/shelltool_test.go Updates and adds tests covering the new allow/deny semantics and custom-callback ordering.
.github/workflows/verify-aw-locks.yml New workflow to re-run gh aw compile with a pinned version and fail if committed lock files drift.
.github/workflows/go-api-consistency-review.lock.yml Regenerated lock file (pins updated to match the pinned gh-aw compiler output).
.github/workflows/dotnet-port-fixes-nightly.lock.yml Regenerated lock file (pins updated to match the pinned gh-aw compiler output).
.github/workflows/dotnet-port-api-nightly.lock.yml Regenerated lock file (pins updated to match the pinned gh-aw compiler output).
.github/workflows/dotnet-code-portability-nightly.lock.yml Regenerated lock file (pins updated to match the pinned gh-aw compiler output).
.github/dependabot.yml Prevent Dependabot from bumping action pins that are embedded by gh aw compile into generated lock files.
Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 1
  • Review effort level: Lite

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

Comment thread tool/shelltool/shelltool.go
@github-actions github-actions Bot added kind:ci Changes CI, build, or repository automation kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure pending-auto-risk Automatic risk classification is in progress labels Sep 9, 2026
@michelle-clayton-work

Copy link
Copy Markdown
Contributor Author

Copilot resolve merge conflicts and address PR feedback

…policy-deny-first-e4eefad3518aecdc

# Conflicts:
#	.github/dependabot.yml
#	.github/workflows/dotnet-code-portability-nightly.lock.yml
#	.github/workflows/dotnet-port-api-nightly.lock.yml
#	.github/workflows/dotnet-port-fixes-nightly.lock.yml
#	.github/workflows/go-api-consistency-review.lock.yml

Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>
@github-actions github-actions Bot added risk:high Large blast radius, difficult rollback, or sensitive behavior and removed pending-auto-risk Automatic risk classification is in progress labels Sep 9, 2026
…back

Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>

Copilot AI commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve merge conflicts and address PR feedback

Done in e4f26dc: merged main into this branch (resolving conflicts by taking main's versions for unrelated generated workflow/config files), and fixed the review feedback so Policy.Evaluate passes a sanitized ShellRequest with the trimmed command to Custom, matching what the deny/allow-list checks see. Added a test covering this.

@github-actions github-actions Bot added size:large At most 300 changed lines across at most 10 files and removed size:xlarge More than 300 changed lines or 10 files labels Sep 9, 2026
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added parity-approved Go API consistency review found no parity issues public-api-change Pull Request changes public APIs pending-auto-risk Automatic risk classification is in progress risk:high Large blast radius, difficult rollback, or sensitive behavior and removed risk:high Large blast radius, difficult rollback, or sensitive behavior pending-auto-risk Automatic risk classification is in progress labels Sep 9, 2026
Comment thread .github/workflows/verify-aw-locks.yml Outdated
@github-actions github-actions Bot removed area:github Changes files in the github area kind:ci Changes CI, build, or repository automation labels Sep 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Scope: public API, user-visible behavior

Changed Go contract: tool/shelltool.Policy/PolicyConfig.Evaluate — evaluation order changed from allow-short-circuits-deny to deny-first with an exclusive allow list, plus a new PolicyConfig.Custom / Policy.custom override callback (func(ShellRequest) (allowed bool, reason string, ok bool)) that runs after deny/allow-list checks.

Upstream evidence reviewed: dotnet/src/Microsoft.Agents.AI.Tools.Shell/ShellPolicy.cs from commit ccba1fbbef9aff7d6e5435fb74f0cc7789ca5243 (microsoft/agent-framework#6906, "[BREAKING] Align ShellPolicy allow/deny semantics with Python"). Reviewed the full commit diff, including the ShellPolicy constructor (denyList, allowList, custom params), Evaluate ordering (empty-command guard → deny list → exclusive allow list → custom override → default allow), and the doc comments describing nil-vs-empty allow list semantics.

Result: aligned. The Go changes are a faithful, semantically equivalent port:

  • Deny-first precedence and exclusive allow-list behavior match the .NET reorder exactly (deny checked before allow; unmatched allow list denies).
  • nil vs empty AllowList distinction matches .NET's null (disabled) vs empty collection (deny-all) semantics.
  • The Custom/custom callback signature ((bool allowed, string reason, bool ok) in Go vs. nullable ShellPolicyOutcome? return in .NET) is an idiomatic Go analogue of .NET's Func<ShellRequest, ShellPolicyOutcome?>, preserving "runs last, cannot re-enable an already-rejected command, no-op when ok/return is false/null" semantics.
  • Evaluation order in Go's updated doc comment (empty-command guard → deny patterns → allow-list denial → custom override → default allow) matches .NET's documented order verbatim.

This is a breaking change in Go, consistent with the upstream .NET PR also being marked [BREAKING], so the divergence from the prior Go behavior is intentional and tracked correctly in the PR description.

No parity issues found. Adding public-api-change since Policy, PolicyConfig.AllowList semantics, and the new PolicyConfig.Custom field are exported API changes.

Generated by Go API Consistency Review Agent for #1047 · copilot · auto · 26.2 AIC · ⌖ 5.41 AIC · ⊞ 9.6K ·

@github-actions github-actions Bot added pending-auto-risk Automatic risk classification is in progress and removed risk:high Large blast radius, difficult rollback, or sensitive behavior labels Sep 11, 2026
@github-actions github-actions Bot added failed-auto-risk Automatic risk classification was inconclusive or failed and removed pending-auto-risk Automatic risk classification is in progress labels Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tool Changes files in the tool area failed-auto-risk Automatic risk classification was inconclusive or failed kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure parity-approved Go API consistency review found no parity issues public-api-change Pull Request changes public APIs size:large At most 300 changed lines across at most 10 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[dotnet-port-api] Align shell policy allow and deny semantics

4 participants