Skip to main content

hessra_context_token/
lib.rs

1//! # Hessra Context Token
2//!
3//! Context token implementation for information flow control (exposure tracking)
4//! in the Hessra authorization system.
5//!
6//! Context tokens track what data an object (typically an AI agent) has been
7//! exposed to during a session. Each data access adds exposure labels as
8//! append-only biscuit blocks, which downstream systems use to restrict
9//! available capabilities.
10//!
11//! ## Key Properties
12//!
13//! - **Append-only**: Exposure labels accumulate and cannot be removed within a session.
14//! - **Issuer-attested**: Each exposure block is a third-party biscuit block signed by
15//!   the issuer's keypair. Verifier rules and queries use `trusting authority, {pubkey}`
16//!   to scope authorization decisions to issuer-attested facts only.
17//! - **Block-stacked**: All labels added in a single call land in the same block.
18//! - **Inheritable**: Child contexts inherit parent exposure via `fork_context`.
19//! - **Pure Datalog authorization**: Exclusion checks run as biscuit deny policies.
20//!   No string parsing on the authz path.
21//!
22//! ## Authority Block
23//!
24//! ```datalog
25//! context(subject);
26//! check if time($time), $time < expiration;
27//! // optional, only if mint-time exposures supplied:
28//! exposure(label_1);
29//! exposure(label_2);
30//! exposure_source(source);
31//! exposure_time(timestamp);
32//! ```
33//!
34//! ## Third-party exposure blocks (one per `add_exposure` call)
35//!
36//! ```datalog
37//! exposure(label_a);
38//! exposure(label_b);
39//! exposure_source(source);
40//! exposure_time(timestamp);
41//! ```
42//!
43//! ## Example
44//!
45//! ```rust
46//! use hessra_context_token::{HessraContext, ContextVerifier, add_exposure};
47//! use hessra_token_core::{KeyPair, TokenTimeConfig};
48//!
49//! let keypair = KeyPair::new();
50//! let public_key = keypair.public();
51//!
52//! // Mint a fresh context token
53//! let token = HessraContext::new("agent:openclaw".to_string(), TokenTimeConfig::default())
54//!     .issue(&keypair)
55//!     .expect("Failed to create context token");
56//!
57//! // Add exposure labels (stacked into one third-party block, signed by the issuer)
58//! let exposed = add_exposure(
59//!     &token,
60//!     &keypair,
61//!     &["PII:SSN".to_string()],
62//!     "data:user-ssn".to_string(),
63//! ).expect("Failed to add exposure");
64//!
65//! // Verify with chained exclusion checks
66//! ContextVerifier::new(exposed.clone(), public_key)
67//!     .excludes("PII:email")
68//!     .verify()
69//!     .expect("PII:email is not attested");
70//!
71//! assert!(ContextVerifier::new(exposed, public_key)
72//!     .excludes("PII:SSN")
73//!     .verify()
74//!     .is_err());
75//! ```
76
77mod exposure;
78mod inspect;
79mod mint;
80mod verify;
81
82pub use exposure::{add_exposure, extract_exposure_labels, fork_context};
83pub use inspect::{ContextInspectResult, inspect_context_token};
84pub use mint::HessraContext;
85pub use verify::ContextVerifier;
86
87// Re-export commonly needed types from core
88pub use hessra_token_core::{
89    Biscuit, KeyPair, PublicKey, TokenError, TokenTimeConfig, decode_token, encode_token,
90    parse_token, public_key_from_pem_file,
91};