typesec_odrl/audit.rs
1//! Audit log types for ODRL policy decisions.
2
3use tracing::info;
4
5use crate::model::OdrlRuleType;
6
7/// A structured audit record for a single ODRL policy check.
8#[derive(Debug)]
9pub struct OdrlAuditEvent {
10 /// The policy UID that produced this verdict.
11 pub policy_uid: String,
12 /// The matched rule type (or `None` if no rule matched).
13 pub matched_rule: Option<OdrlRuleType>,
14 /// The subject making the request.
15 pub subject: String,
16 /// The action requested.
17 pub action: String,
18 /// The target resource.
19 pub target: String,
20 /// The final verdict.
21 pub verdict: OdrlVerdict,
22 /// Constraint evaluation results.
23 pub constraint_results: Vec<ConstraintEval>,
24}
25
26/// Verdict of an ODRL check.
27#[derive(Debug, Clone)]
28pub enum OdrlVerdict {
29 /// A permission rule matched and all constraints passed.
30 Permitted,
31 /// A prohibition rule matched and all constraints passed (action blocked).
32 Prohibited {
33 /// Human-readable reason explaining why the action is prohibited.
34 reason: String,
35 },
36 /// No matching rule found.
37 NotApplicable,
38 /// A permission rule matched but one or more constraints failed.
39 ConstraintFailed {
40 /// Description of the constraint that failed.
41 constraint: String,
42 },
43}
44
45/// Record of a single constraint's evaluation.
46#[derive(Debug, Clone)]
47pub struct ConstraintEval {
48 /// The left operand (e.g., `"purpose"`).
49 pub operand: String,
50 /// Whether it passed.
51 pub passed: bool,
52}
53
54impl OdrlAuditEvent {
55 /// Emit this event to the `tracing` subscriber.
56 pub fn log(&self) {
57 let verdict_str = match &self.verdict {
58 OdrlVerdict::Permitted => "permitted".to_owned(),
59 OdrlVerdict::Prohibited { reason } => format!("prohibited: {reason}"),
60 OdrlVerdict::NotApplicable => "not_applicable".to_owned(),
61 OdrlVerdict::ConstraintFailed { constraint } => {
62 format!("constraint_failed: {constraint}")
63 }
64 };
65
66 info!(
67 policy = %self.policy_uid,
68 subject = %self.subject,
69 action = %self.action,
70 target = %self.target,
71 verdict = %verdict_str,
72 "odrl policy decision"
73 );
74 }
75}