Skip to main content

Crate treetop_core

Crate treetop_core 

Source
Expand description

Usage example:

Here we declare a policy that allows “alice” to create a host if and only if the following conditions are met:

  • The host’s nameLabel set contains “example_domain”. This is created via regular expressions on the name from the initialize_host_patterns function.
  • The host’s IP address is within the network “10.0.0.0/24”.
  • The host’s name contains the letter ‘n’

Note that we do not require the host to have the nameLabel “webserver” for “alice” to create it.

use regex::Regex;
use std::sync::Arc;
use treetop_core::{LabelTarget, Action, AttrValue, PolicyEngine, Request, User, Principal, Resource, RegexLabeler, LabelRegistryBuilder};
use sha2::{Digest, Sha256};

let policies = r#"
permit (
   principal == User::"alice",
   action == Action::"create_host",
   resource is Host
) when {
    resource.nameLabels.contains("in_domain") &&
    resource.ip.isInRange(ip("10.0.0.0/24")) &&
    resource.name like "*n*"
};
"#;

// Used to create attributes for hosts based on their names.
let patterns = vec![
    ("in_domain".to_string(), Regex::new(r"example\.com$").unwrap()),
    ("webserver".to_string(), Regex::new(r"^web-\d+").unwrap()),
];
let label_registry = LabelRegistryBuilder::new()
    .add_labeler(Arc::new(RegexLabeler::new(LabelTarget::new("Host", "nameLabels").unwrap(), "name",
        patterns.into_iter().collect(),
    ).unwrap()))
    .build()
    .unwrap();

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

let request = Request {
   principal: Principal::User(User::new("alice", None, None).unwrap()), // No groups, no namespace
   action: Action::new("create_host", None).unwrap(), // Action is not in a namespace
   resource: Resource::new("Host", "hostname.example.com").unwrap()
    .with_attr("name", AttrValue::String("hostname.example.com".into()))
    .with_attr("ip", AttrValue::ip("10.0.0.1").unwrap())
};

let decision = engine.evaluate(&request).unwrap();
assert!(decision.is_allowed());

// List all of alice's policies
let alice_policies = engine.list_policies_for_user("alice", &[], &[]).unwrap();
// This value is also seralizable to JSON
let json = serde_json::to_string(&alice_policies).unwrap();

// Check that the policy running is the expected version
let expected_hash = Sha256::digest(policies)
    .iter()
    .fold(String::with_capacity(64), |mut s, b| {
        use std::fmt::Write;
        write!(s, "{b:02x}").unwrap();
        s
    });
assert_eq!(engine.current_version().hash.as_ref(), expected_hash);

§Thread-Safe Sharing

For multithreaded applications, wrap PolicyEngine in Arc to share it across threads:

use std::sync::Arc;
use std::thread;

let engine = Arc::new(engine_base);
let engine_clone = Arc::clone(&engine);

let handle = thread::spawn(move || {
    // Evaluate policies in a background thread
    let request = Request {
        principal: Principal::User(User::new("user", None, None).unwrap()),
        action: Action::new("read", None).unwrap(),
        resource: Resource::new("Document", "doc1").unwrap(),
    };
    let _decision = engine_clone.evaluate(&request);
});

handle.join().unwrap();

Re-exports§

pub use types::Action;
pub use types::AttrValue;
pub use types::CedarIp;
pub use types::CedarType;
pub use types::Decision;
pub use types::DecisionDiagnostics;
pub use types::DecisionDto;
pub use types::Group;
pub use types::Groups;
pub use types::PermitPolicies;
pub use types::PermitPolicy;
pub use types::PolicyCandidates;
pub use types::PolicyEffectFilter;
pub use types::PolicyMatch;
pub use types::PolicyMatchReason;
pub use types::PolicyVersion;
pub use types::Principal;
pub use types::Request;
pub use types::RequestContext;
pub use types::Resource;
pub use types::User;
pub use types::action_entity_uid;
pub use types::group_entity_uid;
pub use types::namespace_segments;
pub use types::resource_entity_uid;
pub use types::user_entity_uid;

Modules§

types
Data model types for requests and Cedar entity conversion.

Structs§

BuildInfo
EvaluationSession
A frozen, cheaply cloneable authorization-state generation.
GitInfo
LabelRegistry
Immutable collection of labelers indexed by their declared resource type.
LabelRegistryBuilder
Builder for creating a LabelRegistry with labelers.
LabelSetVersion
Stable application-defined identity for one complete labeling configuration.
LabelTarget
Exclusive ownership of one attribute on one exact Cedar resource type.
PolicyEngine
PolicyStoreConfig
One declared policy store and the Cedar namespace subtree it owns.
PolicyStoreId
A stable application-defined policy-store identifier.
PolicyStoreLayout
Validated configuration for namespace-partitioned policy stores.
RegexLabeler
A labeler that uses regular expressions for matching on resource attributes.
Schema
Object containing schema information used by the validator.
SchemaEnforcing
Marker for an engine that always validates with a Cedar schema.
SchemaFree
Marker for an engine that does not use a Cedar schema.

Enums§

PolicyError
Policy evaluation and validation errors.

Constants§

POLICY_STORE_ANNOTATION
Reserved policy annotation used for explicit local or global assignment.

Traits§

Labeler
Derives one trusted attribute within one declared resource scope.
LabelerApply
Controlled, scope-enforcing application available on every labeler.
ValidationMode
Type-level policy for Cedar schema enforcement.

Functions§

build_info
compile_policy
Compile Cedar policy text into a PolicySet.
compile_policy_with_schema
Compile Cedar policy text into a PolicySet and validate against a schema.