pub struct PolicyEngine { /* private fields */ }Expand description
Evaluates actions against registered policies.
Implementations§
Source§impl PolicyEngine
impl PolicyEngine
pub fn new() -> PolicyEngine
pub fn register( &mut self, name: &str, check: Box<dyn Fn(&Action, &StateStore) -> Option<String> + Sync + Send>, description: &str, )
Sourcepub fn register_tool_deny(
&mut self,
name: &str,
tool: &str,
check: Box<dyn Fn(&Action, &StateStore) -> Option<String> + Sync + Send>,
description: &str,
)
pub fn register_tool_deny( &mut self, name: &str, tool: &str, check: Box<dyn Fn(&Action, &StateStore) -> Option<String> + Sync + Send>, description: &str, )
Self::register, plus the standing fact that check forbids tool
outright — whatever the arguments.
Use this for a rule that denies a whole tool, so it can be read back by
Self::blanket_denied_tools. The check itself is still the caller’s,
deliberately: a file-loaded rule and a host-registered one word their
refusal differently, and centralizing the closure here would make one of
those messages wrong.
Registering a conditional check through this door mislabels it and will hide a tool that is only sometimes denied. There is no way to check that from here — the check is an opaque closure — so the contract is on the caller.
Sourcepub fn check(&self, action: &Action, state: &StateStore) -> Vec<PolicyViolation>
pub fn check(&self, action: &Action, state: &StateStore) -> Vec<PolicyViolation>
Check an action against all policies.
If a policy check panics, the panic is caught and treated as a violation.
Sourcepub fn unregister(&mut self, name: &str) -> usize
pub fn unregister(&mut self, name: &str) -> usize
Remove every policy registered under name. Returns how many were
dropped — 0 when nothing matched, so the caller can distinguish “removed”
from “there was nothing by that name”.
Self::register appends without de-duplicating, so the same name can
legitimately appear more than once; this removes all of them rather than
leaving a shadowed copy still enforcing (Parslee-ai/car#623).
Sourcepub fn blanket_denied_tools(&self) -> BTreeSet<String>
pub fn blanket_denied_tools(&self) -> BTreeSet<String>
The tools this engine forbids outright, whatever the arguments —
the deny_tool rule kind, and only that kind.
For callers that assemble the tool list a model is shown. A tool no call can ever satisfy is worth removing from that list rather than advertising and then refusing: the refusal is correct but costs a turn and a schema’s worth of context on every request.
§Why only deny_tool
Not because the other kinds are “argument-dependent” — several of them can forbid a tool outright too:
allow_tool_paramwith an emptyallowpermits nothing.rate_limit_toolwithmax_calls = 0denies every call.deny_tool_param_matchingwhose pattern fails to compile denies the whole tool, fail-closed.deny_tool_paramwith neitherequalsnorcontainsdenies on the parameter’s mere presence, which is total for a required parameter.
The property that actually separates them is whether totality is
decidable from the rule kind alone, without reading the rule’s
contents. deny_tool is the only kind where it is. The others are
total only by inspection, and a caller assembling a tool list has no
business inspecting them — so this deliberately under-reports rather
than guess. Under-reporting is the safe direction: the tool is
advertised and then refused, which is exactly the old behavior.
A narrow-but-not-total allow_tool_param is the case this leaves on
the table. Hiding is the wrong remedy there (the tool is callable,
just not that way); narrowing the advertised parameter schema to the
permitted values is, and that is a separate change.
Populated by Self::register_tool_deny and emptied in step with
Self::unregister and Self::clear, so it cannot name a tool the
engine no longer blocks. A stale entry here would hide a tool that is
actually allowed, which is the one failure mode worth engineering
against.
Sourcepub fn policy_names(&self) -> Vec<String>
pub fn policy_names(&self) -> Vec<String>
Registered policy names, in registration order. May contain duplicates —
see Self::unregister.
Sourcepub fn policy_details(&self) -> Vec<(String, String)>
pub fn policy_details(&self) -> Vec<(String, String)>
Registered policies as (name, description) pairs, in registration
order. The description is what register was given.
pub fn is_empty(&self) -> bool
Trait Implementations§
Source§impl Default for PolicyEngine
impl Default for PolicyEngine
Source§fn default() -> PolicyEngine
fn default() -> PolicyEngine
Auto Trait Implementations§
impl !RefUnwindSafe for PolicyEngine
impl !UnwindSafe for PolicyEngine
impl Freeze for PolicyEngine
impl Send for PolicyEngine
impl Sync for PolicyEngine
impl Unpin for PolicyEngine
impl UnsafeUnpin for PolicyEngine
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more