Skip to main content

PolicyEngine

Struct PolicyEngine 

Source
pub struct PolicyEngine { /* private fields */ }
Expand description

The main engine handle. Thread-safe and cheaply cloneable.

Cloning is cheap (just increments Arc refcounts), but for multithreaded applications, wrapping in Arc<PolicyEngine> and using Arc::clone() is more idiomatic and makes ownership clearer.

For single-threaded use or when passing the engine to a single thread, you can simply clone it directly.

Implementations§

Source§

impl PolicyEngine

Source

pub fn new_from_str(policy_text: &str) -> Result<Self, PolicyError>

Source

pub fn new_from_str_with_schema( policy_text: &str, schema: Schema, ) -> Result<Self, PolicyError>

Create a new policy engine with schema-based policy and request validation.

Source

pub fn new_from_str_with_cedarschema( policy_text: &str, schema_text: &str, ) -> Result<Self, PolicyError>

Create a new policy engine from policy text and Cedar schema text.

Source

pub fn with_label_registry(self, registry: LabelRegistry) -> Self

Create a new policy engine with a label registry.

This is a convenience method that combines new_from_str and with_label_registry.

Source

pub fn set_label_registry(&mut self, registry: LabelRegistry)

Set or replace the label registry for this engine.

This allows updating the labelers after the engine has been created.

Source

pub fn label_registry(&self) -> Option<&LabelRegistry>

Get a reference to the label registry, if one is configured.

Source

pub fn reload_from_str(&self, policy_text: &str) -> Result<(), PolicyError>

Source

pub fn reload_from_str_with_schema( &self, policy_text: &str, schema: Schema, ) -> Result<(), PolicyError>

Reload policies and replace the engine schema at the same time.

Source

pub fn reload_from_str_with_cedarschema( &self, policy_text: &str, schema_text: &str, ) -> Result<(), PolicyError>

Reload policies and replace the engine schema from Cedar schema text.

Source

pub fn current_version(&self) -> PolicyVersion

Get the current policy version.

The hash is computed from the policy text, and loaded_at reflects when this snapshot was installed.

Source

pub fn evaluate(&self, request: &Request) -> Result<Decision, PolicyError>

Evaluate a policy request against the currently loaded policy set.

This method performs a complete Cedar policy evaluation:

  1. Applies any registered labelers to augment resource attributes
  2. Constructs Cedar entities for the principal (including groups), action, and resource
  3. Executes the Cedar authorization decision
  4. Returns either Allow (with the matching policy) or Deny, both including version metadata
§Arguments
  • request - The authorization request containing the principal, action, and resource
§Returns
  • Ok(Decision::Allow) - If at least one permit policy matches and no forbid policies match
  • Ok(Decision::Deny) - If no permit policies match or if a forbid policy matches
  • Err(PolicyError) - If there’s an error constructing entities, parsing the request, or during evaluation
§Examples
use treetop_core::{PolicyEngine, Request, Principal, User, Action, Resource, Decision};

let policies = r#"
    permit (
        principal == User::"alice",
        action == Action::"read",
        resource == Document::"doc1"
    );
"#;

let engine = PolicyEngine::new_from_str(policies).unwrap();

let request = Request {
    principal: Principal::User(User::new("alice", None, None)),
    action: Action::new("read", None),
    resource: Resource::new("Document", "doc1"),
};

let decision = engine.evaluate(&request).unwrap();
assert!(matches!(decision, Decision::Allow { .. }));

// Access version information
if let Decision::Allow { version, .. } = decision {
    println!("Allowed by policy version: {}", version.hash);
}
§Thread Safety

This method is thread-safe and lock-free. Multiple threads can evaluate requests concurrently without blocking each other.

Source

pub fn evaluate_with_context( &self, request: &Request, request_context: &RequestContext, ) -> Result<Decision, PolicyError>

Evaluate a request with explicit Cedar request context.

Source

pub fn evaluate_with_diagnostics( &self, request: &Request, ) -> Result<DecisionDiagnostics, PolicyError>

Evaluate a request and include deny-side forbid diagnostics.

Source

pub fn evaluate_with_context_and_diagnostics( &self, request: &Request, request_context: &RequestContext, ) -> Result<DecisionDiagnostics, PolicyError>

Evaluate a request with explicit context and include deny diagnostics.

Source

pub fn list_policies_for_user( &self, user: &str, groups: &[&str], namespace: &[&str], ) -> Result<UserPolicies, PolicyError>

List permit-policy candidates whose scope matches a user.

This mirrors PolicyEngine::evaluate input shape for principal identity: user id + groups + shared namespace.

Matching includes all Cedar principal-constraint forms:

  • principal == User::"..."
  • principal in Group::"..."
  • principal
  • principal is User
  • principal is User in Group::"..."

Cedar when and unless clauses are not evaluated. The result is not an authorization decision; use PolicyEngine::evaluate to authorize. Resource constraints are not applied in this method. To additionally filter by policy resource constraints, use PolicyEngine::list_policies_for_user_with_resource.

Output is deterministic: policies are sorted by Cedar policy ID. Each returned policy includes match reasons via UserPolicies::matches().

§Arguments
  • user - User ID
  • groups - Group IDs the user belongs to
  • namespace - Optional shared namespace path for both user and groups
§Returns
  • Ok(UserPolicies) - Matching policies and match metadata
  • Err(PolicyError) - If entity UID construction fails
§Examples
use treetop_core::PolicyEngine;

let policies = r#"
    permit (principal == User::"alice", action, resource);
    permit (principal in Group::"admins", action, resource);
"#;

let engine = PolicyEngine::new_from_str(policies).unwrap();
let user_policies = engine.list_policies_for_user("alice", &["admins"], &[]).unwrap();

assert_eq!(user_policies.policies().len(), 2);
assert!(!user_policies.matches().is_empty());
Source

pub fn list_policies( &self, request: &Request, ) -> Result<UserPolicies, PolicyError>

List permit-policy candidates whose scope matches a concrete request.

This mirrors PolicyEngine::evaluate by accepting &Request and uses:

  • the request principal (including user group membership, if any)
  • the request action
  • the request resource

Cedar when and unless clauses are not evaluated. The result is not an authorization decision. This method defaults to permit policies; use PolicyEngine::list_policies_with_effect for an explicit effect.

Source

pub fn list_policies_with_effect( &self, request: &Request, effect_filter: PolicyEffectFilter, ) -> Result<UserPolicies, PolicyError>

List policy candidates for a request, with explicit effect filtering.

Cedar when and unless clauses are not evaluated.

Source

pub fn list_policies_for_user_with_resource( &self, user: &str, groups: &[&str], namespace: &[&str], resource: Option<&Resource>, ) -> Result<UserPolicies, PolicyError>

List all policies applicable to a user, optionally filtering by resource constraints.

This variant applies both principal and resource constraints:

When resource is None, behavior is equivalent to PolicyEngine::list_policies_for_user.

Returned UserPolicies includes match reasons for principal and, when applicable, resource matches.

Source

pub fn list_policies_for_user_with_resource_and_effect( &self, user: &str, groups: &[&str], namespace: &[&str], resource: Option<&Resource>, effect_filter: PolicyEffectFilter, ) -> Result<UserPolicies, PolicyError>

List all policies applicable to a user with optional resource and effect filtering.

Source

pub fn list_policies_for_group( &self, group: &str, namespace: &[&str], ) -> Result<UserPolicies, PolicyError>

List all policies applicable to a group principal.

Useful when callers model group identities directly as principals (mirroring Principal::Group in PolicyEngine::evaluate).

Resource constraints are not applied in this method. To also filter by resource constraints, use PolicyEngine::list_policies_for_group_with_resource.

Source

pub fn list_policies_for_group_with_resource( &self, group: &str, namespace: &[&str], resource: Option<&Resource>, ) -> Result<UserPolicies, PolicyError>

List all policies applicable to a group principal, optionally filtering by resource constraints.

This applies principal constraints for a group principal and, when resource is provided, resource constraints as well.

Source

pub fn list_policies_for_group_with_resource_and_effect( &self, group: &str, namespace: &[&str], resource: Option<&Resource>, effect_filter: PolicyEffectFilter, ) -> Result<UserPolicies, PolicyError>

List all policies applicable to a group principal with optional resource and effect filtering.

Source

pub fn policies(&self) -> Result<Vec<Policy>, PolicyError>

Trait Implementations§

Source§

impl Clone for PolicyEngine

Source§

fn clone(&self) -> PolicyEngine

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl From<&PolicyEngine> for PolicyVersion

Source§

fn from(engine: &PolicyEngine) -> Self

Converts to this type from the input type.
Source§

impl From<PolicyEngine> for PolicyVersion

Source§

fn from(engine: PolicyEngine) -> Self

Converts to this type from the input type.

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more