Skip to main content

CompiledPolicy

Struct CompiledPolicy 

Source
pub struct CompiledPolicy<'p> { /* private fields */ }
Expand description

A policy with all patterns compiled for one evaluation context.

Compile once per process (or per policy reload) and reuse for every tool call; compilation dominates the cost of a single decision. It borrows the policy (Self::compile) or owns it (Self::compile_owned, for a caller such as openmoat-sdk that keeps one engine for as long as it likes).

Implementations§

Source§

impl CompiledPolicy<'_>

Source

pub fn output_source( &self, action: &Action, cwd: &str, paths: &dyn PathResolver, ) -> Option<String>

What the output of action, run in cwd, is, when it is content an attacker may control (fetch https://docs.example/page): what session taint calls untrusted (a fetch, a web search, an MCP result, an unknown tool; a metadata tool too, which does not taint the session, since a page sets the title and URL a tab list shows), and a shell command that reads from a network host the policy does not allow or from a forge’s command-line client (gh issue view). None for everything else: a read of a file, a local command.

Source

pub fn injected_tokens( &self, source: &Action, cwd: &str, output: &str, ) -> Vec<Token>

The tokens of output, the output of source (an action Self::output_source names), worth keeping: hosts other than the ones source itself reached and than loopback, absolute paths outside the project, and commands of its code spans as the classifier reads them. Hosts are kept in their canonical spelling (host::canonical, ADR-063 §4), as a later call’s hosts are compared. De-duplicated, at most MAX_TOKENS_PER_OUTPUT: URL hosts first, then commands, paths, and words that look like hosts.

Source

pub fn with_injected( &self, decision: Decision, action: &Action, paths: &dyn PathResolver, seen: &dyn InjectedLookup, ) -> Decision

decision for action, tightened by the tokens of untrusted content seen knows: a shell command or a write needs review when a host it reaches, a file it writes or a command it runs came from that content, and the policy does not allow that atom. A command counts only when the call also reaches a host or a file outside the project that the policy does not allow. Never loosens; a deny stays.

Source§

impl CompiledPolicy<'_>

Source

pub fn collection( &self, action: &Action, cwd: &str, paths: &dyn PathResolver, is_dir: &dyn Fn(&str) -> bool, ) -> Staging

What running action in cwd collected outside the project (ADR-061): its reads outside it, as files or folders (is_dir tells them apart; the core does no I/O), and, when it read any, the files a packing or encoding command of it wrote. The caller passes only calls that ran.

Source

pub fn with_staging( &self, decision: Decision, action: &Action, paths: &dyn PathResolver, staging: &Staging, is_dir: &dyn Fn(&str) -> bool, ) -> Decision

decision for action with the @staging-egress <host> atom of each host a send of it goes to, once staging (with what this call itself collects, when the session already collected any) reached a threshold of the policy’s staging: section and the send carries a body, or the send names a staged file. Where a deny or review rule names the atom, its decision is merged (strictest wins); otherwise a reason records it and the verdict stays as it was.

Source§

impl CompiledPolicy<'_>

Source

pub fn exposure( &self, action: &Action, cwd: &str, paths: &dyn PathResolver, ) -> Taint

What running action in cwd exposed its session to: secret material from a read the secrets-paths group names, untrusted content from a fetch, a web search, an unknown tool or an MCP result, except a metadata tool’s (taint.metadata_tools). The caller passes only calls that ran; the parts of an action that cannot be classified expose nothing they can name.

Source

pub fn untrusted_read( &self, action: &Action, cwd: &str, paths: &dyn PathResolver, ) -> Option<(UntrustedKind, String)>

The first untrusted content running action in cwd read, with what kind it is: the same atoms CompiledPolicy::exposure counts, for reports that say where the content came from (ADR-056).

Source

pub fn with_taint( &self, decision: Decision, action: &Action, paths: &dyn PathResolver, taint: &Taint, ) -> Decision

decision for action, tightened by taint: after secret material, network to any host but the secret’s own, and every MCP call, web search and unknown tool (the hosts they reach are unknown), needs review; after untrusted content, a write to a protected path needs review. Merging keeps the strictest verdict, so this never loosens a decision.

Source§

impl<'p> CompiledPolicy<'p>

Source

pub fn compile( policy: &'p Policy, ctx: &EvalContext, ) -> Result<Self, PolicyError>

Compile every pattern of policy for ctx. Fails on a pattern that does not compile, and on a moved_dirs entry whose default could alias every pattern (empty, bare /, or not an absolute or ~/-rooted directory).

Source

pub fn compile_owned( policy: Policy, ctx: &EvalContext, ) -> Result<CompiledPolicy<'static>, PolicyError>

Self::compile for a policy the result keeps, so it borrows nothing.

Source

pub fn policy(&self) -> &Policy

The policy this was compiled from.

Source

pub fn context(&self) -> &EvalContext

The context this was compiled for.

Source

pub fn evaluate_atomic(&self, action: &AtomicAction) -> Option<Decision>

Evaluate one atomic action: deny → allow → review → defer → default, with a repository policy’s review rules (Policy::repo_review) tried before allow.

A repository review never softens what the user’s policy alone decides for the atom: per atom the result is the stricter of the two (ADR-022), so a repository’s review: [{net: ['*']}] leaves a host the net: deny default refuses denied.

Returns None for a whole-pipeline atom that no rule mentions: pipelines are only there so rules like curl * | sh can see across |; the per-sub-command atoms carry the default verdict.

Source§

impl CompiledPolicy<'_>

Source

pub fn decide(&self, action: &Action) -> Decision

Decide one host action without executable resolution.

Unparseable input yields the policy’s catch-all verdict (review or defer) with the parser’s reason, never allow.

Source

pub fn atoms( &self, action: &Action, paths: &dyn PathResolver, ) -> (Vec<AtomicAction>, Option<String>)

The atomic actions Self::decide_with evaluates for action, with an extra atom for every path an unquoted glob operand names in the directories paths lists, and for every read or write paths resolves through a symlink; and the reason when part of the action cannot be classified or a glob not expanded in full (review).

Source

pub fn pushes(&self, action: &Action) -> Vec<Push>

The commands of action that publish local commits (git push, gh pr create), each with the directories it may run in. Only a shell command has any.

Source

pub fn executed(&self, action: &Action, paths: &dyn PathResolver) -> Vec<String>

The files action runs as code (ADR-039): a script an interpreter or a shell runs (python3 x.py, bash x.sh, source x), a file it loads first (node -r ./x.js) and a program named by a path (./x), through every wrapper the classifier unwraps (env, time, bash -c '…'), as canonical paths, each also as paths resolves it through a symlink. Only a shell command runs any; a test runner, build tool or package script (pytest, npm test, go run .) names none.

Source

pub fn decide_with( &self, action: &Action, resolver: &dyn ProgramResolver, paths: &dyn PathResolver, ) -> Decision

Decide one host action, resolving shell programs through resolver so that executables pins and installation pins are enforced, and paths through paths so a symlink cannot move a read or write past a rule.

Trait Implementations§

Source§

impl<'p> Debug for CompiledPolicy<'p>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'p> Forget for CompiledPolicy<'p>

§

impl<'p> Freeze for CompiledPolicy<'p>

§

impl<'p> RefUnwindSafe for CompiledPolicy<'p>

§

impl<'p> Send for CompiledPolicy<'p>

§

impl<'p> Sync for CompiledPolicy<'p>

§

impl<'p> Unpin for CompiledPolicy<'p>

§

impl<'p> UnsafeUnpin for CompiledPolicy<'p>

§

impl<'p> UnwindSafe for CompiledPolicy<'p>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.