Problem
An agent that is goal-hijacked or simply mistaken can invoke destructive tools (email delete, DB drop, git push --force, file deletion) with no human checkpoint. There is no confirmation and no way to see the effect of a state-changing call before it happens.
Current state
cli_execute enforces a no-shell sandbox, binary allowlist, and arg validation (forge-cli/tools/cli_execute.go), and egress is fail-closed (forge-core/security/resolver.go:12). Tool invocations are audited via tool_exec (forge-core/runtime/audit.go:20). But we do not gate destructive actions behind explicit approval, and there is no dry-run/preview that separates preview from effect. See docs/security/owasp-asi-conformance.md (ASI02, ASI09).
Proposed control
Prefer a policy-layer addition over a new forge-core builtin:
- A tool classification (
requires_approval) in the policy layer.
- A preview mode that blocks state-changing calls and emits an
approval_required (or guardrail_check) audit event, with the approval surfaced by the Platform.
Acceptance criteria
Conformance test
TestASI02_DestructiveActionRequiresApproval, TestASI09_PreviewBlocksEffect (must go fail -> pass; assert on the block/approval audit event, not absence of output).
Out of scope
Approval UX/workflow (Platform). Model-side refusal. This does not address prompt injection itself.
Guideline reference
ASI02 mitigation #2 and ASI09 mitigation #1/#7 (OWASP Agentic Top 10 2026). Deduplicated: single control closes both.
Problem
An agent that is goal-hijacked or simply mistaken can invoke destructive tools (email delete, DB drop,
git push --force, file deletion) with no human checkpoint. There is no confirmation and no way to see the effect of a state-changing call before it happens.Current state
cli_executeenforces a no-shell sandbox, binary allowlist, and arg validation (forge-cli/tools/cli_execute.go), and egress is fail-closed (forge-core/security/resolver.go:12). Tool invocations are audited viatool_exec(forge-core/runtime/audit.go:20). But we do not gate destructive actions behind explicit approval, and there is no dry-run/preview that separates preview from effect. Seedocs/security/owasp-asi-conformance.md(ASI02, ASI09).Proposed control
Prefer a policy-layer addition over a new forge-core builtin:
requires_approval) in the policy layer.approval_required(orguardrail_check) audit event, with the approval surfaced by the Platform.Acceptance criteria
requires_approvalcannot execute without an approval signal.TestNoPayloadByDefault_LLMCallinvariant unchanged.Conformance test
TestASI02_DestructiveActionRequiresApproval,TestASI09_PreviewBlocksEffect(must go fail -> pass; assert on the block/approval audit event, not absence of output).Out of scope
Approval UX/workflow (Platform). Model-side refusal. This does not address prompt injection itself.
Guideline reference
ASI02 mitigation #2 and ASI09 mitigation #1/#7 (OWASP Agentic Top 10 2026). Deduplicated: single control closes both.