pub struct PolicyEngine { /* private fields */ }Expand description
The core policy evaluation engine.
Evaluates Actions against a set of Policy rules to produce a Verdict.
§Security Model
- Fail-closed: An empty policy set produces
Verdict::Deny. - Priority ordering: Higher-priority policies are evaluated first.
- Pattern matching: Policy IDs use
"tool:function"convention with wildcard support.
Implementations§
Source§impl PolicyEngine
impl PolicyEngine
Sourcepub fn compile_policies(
policies: &[Policy],
strict_mode: bool,
) -> Result<Vec<CompiledPolicy>, Vec<PolicyValidationError>>
pub fn compile_policies( policies: &[Policy], strict_mode: bool, ) -> Result<Vec<CompiledPolicy>, Vec<PolicyValidationError>>
Compile a set of policies, validating all patterns at load time.
Returns pre-sorted Vec<CompiledPolicy> on success, or a list of
all validation errors found across all policies on failure.
Source§impl PolicyEngine
impl PolicyEngine
Sourcepub fn evaluate_action_traced(
&self,
action: &Action,
) -> Result<(Verdict, EvaluationTrace), EngineError>
pub fn evaluate_action_traced( &self, action: &Action, ) -> Result<(Verdict, EvaluationTrace), EngineError>
Evaluate an action with full decision trace.
Opt-in alternative to Self::evaluate_action that records per-policy match
details for OPA-style decision explanations. Has ~20% allocation overhead
compared to the non-traced hot path, so use only when ?trace=true.
Source§impl PolicyEngine
impl PolicyEngine
Sourcepub fn new(strict_mode: bool) -> Self
pub fn new(strict_mode: bool) -> Self
Create a new policy engine.
When strict_mode is true, the engine applies stricter validation
on conditions and parameters.
Sourcepub fn strict_mode(&self) -> bool
pub fn strict_mode(&self) -> bool
Returns the engine’s strict_mode setting.
Sourcepub fn validate_domain_pattern(pattern: &str) -> Result<(), String>
pub fn validate_domain_pattern(pattern: &str) -> Result<(), String>
Validate a domain pattern used in network_rules.
Rules per RFC 1035:
- Labels (parts between dots) must be 1-63 characters each
- Each label must be alphanumeric + hyphen only (no leading/trailing hyphen)
- Total domain length max 253 characters
- Wildcard
*.prefix is allowed (only at the beginning) - Empty string is rejected
See the internal domain::validate_domain_pattern function for details.
Sourcepub fn with_policies(
strict_mode: bool,
policies: &[Policy],
) -> Result<Self, Vec<PolicyValidationError>>
pub fn with_policies( strict_mode: bool, policies: &[Policy], ) -> Result<Self, Vec<PolicyValidationError>>
Create a new policy engine with pre-compiled policies.
All regex and glob patterns are compiled at construction time. Invalid patterns cause immediate rejection with descriptive errors. The compiled policies are sorted by priority (highest first, deny-overrides).
Sourcepub fn set_max_path_decode_iterations(&mut self, max: u32)
pub fn set_max_path_decode_iterations(&mut self, max: u32)
Set the maximum percent-decoding iterations for path normalization.
Paths requiring more iterations fail-closed to "/". The default is
DEFAULT_MAX_PATH_DECODE_ITERATIONS (20). A value of 0 disables
iterative decoding entirely (single pass only).
Sourcepub fn sort_policies(policies: &mut [Policy])
pub fn sort_policies(policies: &mut [Policy])
Sort policies by priority (highest first), with deny-overrides at equal priority, and a stable tertiary tiebreaker by policy ID for deterministic ordering.
Call this once when loading or modifying policies, then pass the sorted
slice to Self::evaluate_action to avoid re-sorting on every evaluation.
Sourcepub fn evaluate_action(
&self,
action: &Action,
policies: &[Policy],
) -> Result<Verdict, EngineError>
pub fn evaluate_action( &self, action: &Action, policies: &[Policy], ) -> Result<Verdict, EngineError>
Evaluate an action against a set of policies.
For best performance, pass policies that have been pre-sorted with
Self::sort_policies. If not pre-sorted, this method will sort a temporary
copy (which adds O(n log n) overhead per call).
The first matching policy determines the verdict. If no policy matches, the default is Deny (fail-closed).
Sourcepub fn evaluate_action_with_context(
&self,
action: &Action,
policies: &[Policy],
context: Option<&EvaluationContext>,
) -> Result<Verdict, EngineError>
👎Deprecated since 4.0.1: policies parameter is silently ignored when compiled policies exist. Use evaluate_action() for compiled engines or build a new engine with with_policies() for dynamic policy sets.
pub fn evaluate_action_with_context( &self, action: &Action, policies: &[Policy], context: Option<&EvaluationContext>, ) -> Result<Verdict, EngineError>
policies parameter is silently ignored when compiled policies exist. Use evaluate_action() for compiled engines or build a new engine with with_policies() for dynamic policy sets.
Evaluate an action with optional session context.
This is the context-aware counterpart to Self::evaluate_action.
When context is Some, context conditions (time windows, call limits,
agent identity, action history) are evaluated. When None, behaves
identically to evaluate_action.
§WARNING: policies parameter ignored when compiled policies exist
When the engine was constructed with Self::with_policies (or any
builder that populates compiled_policies), the policies parameter
is completely ignored. The engine uses its pre-compiled policy set
instead.
Sourcepub fn evaluate_with_context(
&self,
action: &Action,
context: Option<&EvaluationContext>,
) -> Result<Verdict, EngineError>
pub fn evaluate_with_context( &self, action: &Action, context: Option<&EvaluationContext>, ) -> Result<Verdict, EngineError>
Evaluate an action with optional session context, returning only the verdict.
This is the context-aware counterpart to Self::evaluate_action.
When context is Some, context conditions (time windows, call limits,
agent identity, action history) are evaluated. When None, behaves
identically to evaluate_action.
For the full decision trace, use Self::evaluate_action_traced_with_context.
Sourcepub fn evaluate_action_traced_with_context(
&self,
action: &Action,
context: Option<&EvaluationContext>,
) -> Result<(Verdict, EvaluationTrace), EngineError>
pub fn evaluate_action_traced_with_context( &self, action: &Action, context: Option<&EvaluationContext>, ) -> Result<(Verdict, EvaluationTrace), EngineError>
Evaluate an action with full decision trace and optional session context.
Sourcepub fn normalize_path(raw: &str) -> Result<String, EngineError>
pub fn normalize_path(raw: &str) -> Result<String, EngineError>
Normalize a file path: resolve .., ., reject null bytes, ensure deterministic form.
Handles percent-encoding, null bytes, and path traversal attempts.
Sourcepub fn normalize_path_bounded(
raw: &str,
max_iterations: u32,
) -> Result<String, EngineError>
pub fn normalize_path_bounded( raw: &str, max_iterations: u32, ) -> Result<String, EngineError>
Normalize a file path with a configurable percent-decoding iteration limit.
Use this variant when you need to control the maximum decode iterations to prevent DoS from deeply nested percent-encoding.
Sourcepub fn extract_domain(url: &str) -> String
pub fn extract_domain(url: &str) -> String
Extract the domain from a URL string.
Returns the host portion of the URL, or the original string if parsing fails.
Sourcepub fn match_domain_pattern(domain_str: &str, pattern: &str) -> bool
pub fn match_domain_pattern(domain_str: &str, pattern: &str) -> bool
Match a domain against a pattern like *.example.com or example.com.
Supports wildcard patterns with *. prefix for subdomain matching.
Sourcepub fn get_param_by_path<'a>(params: &'a Value, path: &str) -> Option<&'a Value>
pub fn get_param_by_path<'a>(params: &'a Value, path: &str) -> Option<&'a Value>
Retrieve a parameter value by dot-separated path.
Supports both simple keys ("path") and nested paths ("config.output.path").
Resolution order (Exploit #5 fix): When the path contains dots, the function
checks both an exact key match (e.g., params["config.path"]) and dot-split
traversal (e.g., params["config"]["path"]).
Ambiguity handling (fail-closed): If both interpretations resolve to different
values, the function returns None. This prevents an attacker from shadowing a
nested value with a literal dotted key (or vice versa). The None triggers
deny behavior through the constraint’s on_missing handling.
When only one interpretation resolves, that value is returned. When both resolve to the same value, that value is returned.
IMPROVEMENT_PLAN 4.1: Also supports bracket notation for array access:
items[0]— access first element of array “items”config.items[0].path— traverse nested path with array accessmatrix[0][1]— multi-dimensional array access
Sourcepub fn has_ip_rules(&self) -> bool
pub fn has_ip_rules(&self) -> bool
Returns true if any compiled policy has IP rules configured.
Used by proxy layers to skip DNS resolution when no policies require it.