pub struct PolicyTree {
evaluators: Vec<Arc<dyn Evaluator>>,
predicates: Vec<Predicate>,
index: ShapeIndex,
}Expand description
The built applicability index: every registered policy’s predicate, and the decision and observation trees to route a subject through.
Built once, from a fixed set of PolicyDeclarations, via
PolicyTreeBuilder. PolicyId order is registration order, which is
this server’s presentational evaluation order — see PolicyId’s doc
comment.
Fields§
§evaluators: Vec<Arc<dyn Evaluator>>§predicates: Vec<Predicate>§index: ShapeIndexImplementations§
Source§impl PolicyTree
impl PolicyTree
Sourcepub fn builder() -> PolicyTreeBuilder
pub fn builder() -> PolicyTreeBuilder
Start building a tree.
Sourcepub fn evaluators(&self) -> impl Iterator<Item = &Arc<dyn Evaluator>>
pub fn evaluators(&self) -> impl Iterator<Item = &Arc<dyn Evaluator>>
Every evaluator this tree holds, each named once regardless of how many policies it serves.
A lifecycle event (froze, unfroze, deleted — see
Evaluator::lifecycle) is about an account, not a subject shape
or a collection, so it has no applicability to route it through the
way decision_candidates and
observation_candidates do for a
subject. A caller telling every evaluator about a lifecycle
event — see plan/policy.md’s “An evaluator can never unfreeze […]
the evaluator must be told, or the state that triggered the freeze
survives the unfreeze and slams it shut again” — needs the complete
set, not a filtered one, which is what this returns.
Sourcepub fn evaluator(&self, policy: PolicyId) -> Option<&dyn Evaluator>
pub fn evaluator(&self, policy: PolicyId) -> Option<&dyn Evaluator>
The evaluator responsible for policy, if it has one.
None for a policy whose Predicate is
Unusable — there is nothing to call
observe or lifecycle on. A caller walking
observation_candidates skips such
a policy for those two channels; decide already
accounts for it on the decision channel.
Panics if policy did not come from this tree — the same programmer
error as indexing a Vec out of bounds, and treated the same way.
Sourcepub fn compiled_id(&self, policy: PolicyId) -> Option<CompiledId>
pub fn compiled_id(&self, policy: PolicyId) -> Option<CompiledId>
The compiled artifact policy’s evaluator was told to use, if it
has one — see CompiledId’s doc comment. None for a policy
whose predicate is Unusable, same as
evaluator: there is no artifact to name.
Panics if policy did not come from this tree — see
evaluator.
Sourcepub fn decide_detailed(
&self,
subject: &Subject<'_>,
policy: PolicyId,
) -> (Outcome, bool)
pub fn decide_detailed( &self, subject: &Subject<'_>, policy: PolicyId, ) -> (Outcome, bool)
decide, plus whether the outcome is the evaluator’s
own decision (false) or a fail-closed refusal this tree substituted
because the evaluator could not answer at all (true): an
EvalError, or a predicate that never
compiled. The gate never needs the difference — both refuse alike —
but a page explaining a refusal to an operator does: “the policy
refused this” and “the policy could not be checked” are different
claims, and only this method’s caller can tell them apart.
Panics if policy did not come from this tree — see
evaluator.
Sourcepub fn decision_candidates(&self, subject: &Subject<'_>) -> Vec<PolicyId>
pub fn decision_candidates(&self, subject: &Subject<'_>) -> Vec<PolicyId>
The ordered candidate policies this subject may be decided by.
For a write matching nothing, this costs only a tree walk bounded by the write’s own changed paths, never by how many policies are registered — no evaluator is invoked.
Sourcepub fn observation_candidates(&self, subject: &Subject<'_>) -> Vec<PolicyId>
pub fn observation_candidates(&self, subject: &Subject<'_>) -> Vec<PolicyId>
The ordered set of policies whose observation surface — not necessarily their decision surface — this subject falls under.
Independent of decision_candidates:
a policy can watch attempts it has no say in deciding.