a3s_code_core/permissions/mod.rs
1//! Permission system for tool execution control
2//!
3//! Implements a declarative permission system similar to Claude Code's permissions.
4//! Supports pattern matching with wildcards and three-tier evaluation:
5//! 1. Deny rules - checked first, any match = immediate denial
6//! 2. Allow rules - checked second, any match = auto-approval
7//! 3. Ask rules - checked third, forces confirmation prompt
8//! 4. Default behavior - falls back to HITL policy
9
10mod interactive;
11mod manager;
12mod policy;
13mod rule;
14
15#[cfg(test)]
16mod tests;
17
18use serde::{Deserialize, Serialize};
19
20pub use interactive::{InteractiveApprovalMode, InteractiveToolGuardrail};
21pub use manager::{MatchingRules, PermissionManager};
22pub use policy::PermissionPolicy;
23pub use rule::PermissionRule;
24
25/// Trait for checking tool execution permissions.
26///
27/// Implement this trait to provide custom permission logic.
28/// The built-in `PermissionPolicy` implements this trait using
29/// declarative allow/deny/ask rules with pattern matching.
30pub trait PermissionChecker: Send + Sync {
31 /// Whether a tool definition should be exposed to the model.
32 ///
33 /// This controls model-visible capabilities only. [`Self::check`] remains
34 /// the authoritative execution-time decision for any tool invocation.
35 /// Existing checkers expose every tool unless they explicitly override
36 /// this method.
37 fn expose_to_model(&self, _tool_name: &str) -> bool {
38 true
39 }
40
41 /// Check whether a tool invocation is allowed, denied, or requires confirmation.
42 fn check(&self, tool_name: &str, args: &serde_json::Value) -> PermissionDecision;
43}
44
45/// Permission decision result
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
47#[serde(rename_all = "snake_case")]
48pub enum PermissionDecision {
49 /// Automatically allow without user confirmation
50 Allow,
51 /// Deny execution
52 Deny,
53 /// Ask user for confirmation
54 Ask,
55}