microsoft / microsoft/agent-governance-toolkit
[Bug]: OpenCode default policy can permit recursive deletion and review is non-blocking
- Dominant language
- Python
- Stars
- 6.3k
- Forks
- 1.1k
- Avg merge
- 5d 11h
- Merged PRs (30d)
- 142
Description
## Package
Other — `agent-governance-opencode`
## Description
The bundled default OpenCode policy can permit a recursive deletion command because two behaviors compound:
1. The `recursive-delete` pattern in `config/default-policy.json` uses `\b-rf\b`. The boundary before `-rf` can never match because both the preceding space and the hyphen are non-word characters.
2. The command therefore falls through to the default `reviewTools` handling for `bash`. `normalizeEffectForOpenCode` returns `review` in both advisory and enforce modes, and the OpenCode hook only appends `__agt_review_reason`; nothing blocks execution.
Current implementation:
```js
return state.policy.mode === "advisory" ? "review" : "review";
```
The result is that a clean installation's default policy evaluates `rm -rf /` as `review`, while the session status and audit trail indicate governance is active.
## How does this impact your work?
This is a critical fail-open path in the shipped default configuration. Operators naturally place high-impact tools in `reviewTools`, but on the OpenCode surface `review` currently behaves like allow unless another host permission layer intervenes.
The current workaround is to keep `reviewTools` empty, use `defaultEffect: "deny"`, and provide human approval through the host's native permission system.
## Steps to Reproduce
```js
import { loadPolicy, evaluateOpenCodeTool } from "@microsoft/agent-governance-opencode/policy";
const state = await loadPolicy({ auditPath: "/tmp/audit.json" });
console.log(await evaluateOpenCodeTool(state, {
tool: "bash",
args: { command: "rm -rf /" },
cwd: "/app",
sessionId: "x",
}));
// observed: { effect: "review", reason: "" }
// expected: deny
```
Also test `rm -fr`, `rm -r -f`, `rm --recursive --force`, and mixed short-flag forms.
## Suggested resolution / acceptance criteria
- Replace the recursive-delete expression with order-independent checks for recursive and force flags, including long forms.
- Add regression tests over the shipped default policy for all common flag arrangements.
- Define enforce-mode `review` semantics explicitly:
- preferably normalize `review` to `deny` when the OpenCode host cannot complete an approval; or
- clearly document that it is non-blocking and expose that limitation in policy status.
- Ensure the default configuration cannot silently permit a command that its own deny rule intends to block.
## Environment
- `@microsoft/agent-governance-opencode@5.0.0`
- `@microsoft/agent-governance-sdk@3.7.0`
- Node 26.7.0
- macOS arm64
- Verified against AGT commit `81955d4`
## Code of Conduct
- [x] I agree to follow the Microsoft Open Source Code of Conduct
## Coordination status
- Active implementation: #3676.
- Related overlapping work: #3251, a broader cross-integration recursive-delete parser.
Contributors should coordinate on those active PRs rather than open a parallel implementation.
Contributor guide
Research direction
Start with config/default-policy.json and normalizeEffectForOpenCode, then run the reproduction for rm -rf / and the listed flag variants. Review the active implementation in #3676 and overlapping work in #3251 before changing anything. Done means the shipped default policy rejects all covered recursive-delete forms and enforce-mode review behavior is explicitly resolved or exposed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- authorization, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100