1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! # Chronix Authz — Cedar-based Authorization
//!
//! Fine-grained authorization for the Chronix time-series database using
//! the [Cedar](https://www.cedarpolicy.com/) policy language (formally
//! verified, pure Rust).
//!
//! ## Architecture
//!
//! ```text
//! Request → AuthMiddleware → AuthContext
//! │
//! ▼
//! AuthzEngine (Cedar)
//! ├── PolicySet (hot-reloadable)
//! ├── Entities (principal, resource, roles)
//! └── Decision: Allow | Deny { reasons }
//! ```
//!
//! ## Policy Model
//!
//! - **Principals:** `Chronix::User`, with role membership via `Chronix::Role`
//! - **Resources:** `Chronix::Namespace` for data, `Chronix::System` for
//! administration — the two things `chronixd` asks about, and nothing else
//! - **Actions:** `Read`, `Write`, `Delete` on a namespace; the capabilities
//! in the `Admin` group on the system
//!
//! The model is compiled in as a Cedar schema ([`engine::SCHEMA_SRC`])
//! and **every policy is validated against it**, so a rule naming something
//! this server never asks about is refused at load rather than accepted and
//! never consulted.
//!
//! ## Default-Deny
//!
//! If no policy explicitly permits a request, it is denied. Use `forbid`
//! policies to create hard denials that override permissive policies.
//!
//! ## Example
//!
//! ```
//! use chronix_security::authz::{
//! AuthzEngine, ChronixAction, ChronixNamespace, ChronixPrincipal,
//! };
//!
//! let engine = AuthzEngine::new();
//! engine.load_policies(r#"
//! permit(
//! principal in Chronix::Role::"operator",
//! action in [Chronix::Action::"Read", Chronix::Action::"Write"],
//! resource == Chronix::Namespace::"production"
//! );
//! "#).unwrap();
//!
//! let operator = ChronixPrincipal::new("alice").with_role("operator");
//! let production = ChronixNamespace::new("production");
//! assert!(engine
//! .authorize_namespace(&operator, ChronixAction::Write, &production)
//! .is_allowed());
//! assert!(engine
//! .authorize_namespace(&operator, ChronixAction::Delete, &production)
//! .is_denied());
//! ```
pub use ;
pub use AuthzError;
pub use ;