Skip to main content

ParsedPolicy

Struct ParsedPolicy 

Source
pub struct ParsedPolicy {
    pub rules: Vec<PolicyRule>,
    pub allow_rules: Vec<AllowRule>,
    pub layer_rules: Vec<LayerRule>,
    pub only_rules: Vec<OnlyRule>,
    pub errors: Vec<PolicyError>,
    pub used_aliases: BTreeMap<String, BTreeSet<String>>,
}
Expand description

The rule kinds parsed from a CANDOR_POLICY file.

Fields§

§rules: Vec<PolicyRule>§allow_rules: Vec<AllowRule>§layer_rules: Vec<LayerRule>§only_rules: Vec<OnlyRule>

⟨0.29⟩ the only <A> -> <B> … permission rules — see OnlyRule. Kept in their own list rather than folded into layer_rules because the two read OPPOSITE ways: a forbid names what must not happen, an only names the complete set of what may, so a route that handled one as the other would inverse the verdict rather than approximate it.

§errors: Vec<PolicyError>

⟨0.24⟩ POLICY ERRORS — a policy that cannot be honoured AS WRITTEN (SPEC §6.2). Non-empty ⇒ every gate route MUST refuse: exit 2, the unreadable-policy posture. Not a warning list: the rules in rules are what the text would mean if the error were tolerated, and tolerating it is the defect.

Today the only member is an unrecognised reason-class/alias token in an Unknown[…] filter. The asymmetry that used to justify a warning — “a dropped policy token leaves a WIDER rule standing, so the failure is loud” — is false in the case that matters, and the false half is FAIL-OPEN:

  • deny Unknown[corp] (sole unrecognised token) — the filter empties and the rule WIDENS to a bare deny Unknown, while the engine prints “ignoring policy rule” and then KEEPS and re-scopes it. Merely surprising, but a FALSE DISCLOSURE.
  • deny Unknown[dispatch,nativ] (a typo BESIDE valid tokens) — the token is dropped, the rule NARROWS to [dispatch], and it stops gating native-caused holes entirely while the operator reads a gate that looks armed. That is the fail-open, and it is the common case: a typo lands beside correct tokens far more often than alone.

A policy that cannot be honoured as written is not silently rewritten into a different policy.

⟨0.24⟩ THIS LIST NOW HOLDS EVERY LINE THE PARSER DID NOT HONOUR, fatal or not (SPEC §3.1 195d45a) — parsepolicy reports them all, and the gate routes refuse on ParsedPolicy::fatal_messages alone. Widening the LIST without widening what REFUSES is the whole of the change: a dropped nonsense line was always survivable and stays so.

§used_aliases: BTreeMap<String, BTreeSet<String>>

⟨0.24⟩ The .candor/config unknown-alias definitions this policy actually resolved a token through (SPEC §3.1) — name → the reason-class TOKENS it expanded to, not a bare name list. Non-empty ⇒ a config file supplied vocabulary that PARTICIPATED in the verdict, and the --gate-json document MUST name that file. Recorded at the point of USE, not from the alias map: a config defining ten aliases none of which the policy mentions changed nothing, and naming it would train the reader to ignore the field.

⟨0.24⟩ THE VALUE TRAVELS WITH THE NAME, AND THAT IS A SPEC MUST (§3.1, candor-spec 7f5b5ba). This engine shipped the bare name — as did java and swift — and candor-ts kept the map and won the argument from the clause’s OWN sentence: configSources: [path] is rejected there because a disclosure that names the source but not the content leaves the reader knowing they were affected and not how, and ["corp"] fails that same test one level down. corp = reflect and corp = reflect,native gate DIFFERENTLY under one unchanged policy line, so a reader given only the name cannot tell which gate ran. The map is a strict superset — the keys recover the old array.

Class TOKENS rather than ReasonClass, so the wire order is the token’s alphabetical one (which is what candor-ts’s [...set].sort() produces) and not ReasonClass’s declaration order.

Implementations§

Source§

impl ParsedPolicy

Source

pub fn fatal_messages(&self) -> Vec<&str>

⟨0.24⟩ The messages of the errors that make the policy UNHONOURABLE — what every gate route refuses on. Non-empty ⇒ exit 2, the unreadable-policy posture.

Separate from errors because REPORTED and FATAL are different questions, and conflating them in either direction is a defect: refusing on every dropped line would make nonsense line fail a build, and reporting only the fatal ones is the silent narrowing this rung exists to close.

Trait Implementations§

Source§

impl Debug for ParsedPolicy

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for ParsedPolicy

Source§

fn default() -> ParsedPolicy

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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, <T as TryFrom<U>>::Error>

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.