Skip to content

feat(security): runtime scope policy enforcement for agent tools#3

Merged
adrien-barret merged 10 commits into
masterfrom
002-scope-policy-v2
Mar 11, 2026
Merged

feat(security): runtime scope policy enforcement for agent tools#3
adrien-barret merged 10 commits into
masterfrom
002-scope-policy-v2

Conversation

@adrien-barret
Copy link
Copy Markdown

Summary

  • Add [scope_policy] config section to whitelist allowed repos, HTTP domains, file paths, and scoped commands
  • Implement ScopePolicy runtime validator with 4 check methods (check_http_url, check_shell_command, check_git_repo, check_file_path)
  • Enforce scope checks in 5 existing tools (http_request, shell, git_operations, file_write, file_edit) — hard block before any side-effect
  • Add advisory scope_check tool for LLM pre-flight verification
  • 47 new tests covering all validation paths (allowed, denied, disabled)

Motivation

Prompt-based guardrails are not sufficient for production agent deployments. This PR adds runtime enforcement so that even if the LLM ignores instructions, the tool layer refuses to execute out-of-scope actions with an explicit error message.

Files changed (12)

File Change
src/config/schema.rs ScopePolicyConfig, ScopedRepo structs, validation
src/config/mod.rs Re-export new config types
src/security/scope_policy.rs New — core validation logic (427 lines)
src/security/mod.rs Module registration
src/tools/scope_check.rs New — advisory LLM tool (304 lines)
src/tools/mod.rs Wiring, factory changes
src/tools/http_request.rs Scope enforcement
src/tools/shell.rs Scope enforcement
src/tools/git_operations.rs Scope enforcement
src/tools/file_write.rs Scope enforcement
src/tools/file_edit.rs Scope enforcement
src/onboard/wizard.rs Default scope_policy field

Test plan

  • ScopePolicyConfig parsing tests (valid TOML, invalid TOML, defaults) — 4 tests
  • ScopePolicy check methods (allowed, denied, disabled) — 16 tests
  • ScopeCheckTool advisory responses — 14 tests
  • Tool enforcement (http, shell, git, file_write, file_edit) — 13 tests
  • scope_policy: None preserves existing tool behavior
  • cargo check passes cleanly (verified locally)

🤖 Generated with Claude Code

adrien-barret and others added 10 commits March 11, 2026 10:27
Add ScopePolicyConfig and ScopedRepo structs to config schema with:
- enabled (bool, default false)
- allowed_repos (Vec<ScopedRepo> with non-empty paths validation)
- allowed_http_domains, allowed_file_paths, scoped_commands
- Default scoped_commands: ["gh", "gcloud"]
- Validation bail! for empty paths in allowed_repos
- 4 unit tests: default values, TOML parsing, validation, missing section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ScopePolicy struct with check_http_url, check_shell_command,
check_git_repo, and check_file_path methods. Compiled from
ScopePolicyConfig via from_config(). All methods short-circuit
when policy is disabled. 16 unit tests covering allowed, denied,
and disabled scenarios for each check method.
Wire ScopePolicy construction and passing in all_tools_with_runtime
and default_tools_with_runtime. Register scope_check module.
Teammates will implement the tool structs to accept the new parameter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add scope policy check in HttpRequestTool.execute() before validate_url().
Accepts Option<Arc<ScopePolicy>> in constructor. Logs warn on violation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ScopePolicy to ShellTool. check_shell_command runs before rate
limit. Unscoped commands pass through. Existing tests updated for
new constructor signatures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Advisory tool wrapping ScopePolicy check methods. The LLM calls
scope_check with action_type (http|shell|git|file) and target to
pre-validate actions before execution.

Returns structured JSON {allowed, reason}. When scope_policy is None,
returns allowed=true with "scope policy not configured".

Includes unit tests for all action types, enabled/disabled policy,
missing policy, unknown action type, and missing parameters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Option<Arc<ScopePolicy>> to FileWriteTool and FileEditTool.
check_file_path is called before the autonomy check (can_act),
refusing paths outside allowed_file_paths.
Existing tests pass with scope=None. New tests cover denied
(/etc/) and allowed (/zeroclaw-data/workspace/) paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove user_agent field from HttpRequestTool (not in AdeptMind/master)
- Export ScopePolicyConfig and ScopedRepo from config module
- Drop coordination/syscall/WasmRuntime references (artemislab-only)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@adrien-barret adrien-barret merged commit 2ed2712 into master Mar 11, 2026
3 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants