Skip to main content

idprova_core/trust/
level.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// Trust levels for IDProva agent identities.
5///
6/// Higher levels require more verification and provide stronger guarantees.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
8pub enum TrustLevel {
9    /// Self-declared identity. No verification. Any agent can claim L0.
10    L0,
11    /// Domain-verified. DNS TXT record proves domain ownership.
12    L1,
13    /// Organization-verified. CA-like verification of the controlling organization.
14    L2,
15    /// Audited. Third-party security audit of the agent and its environment.
16    L3,
17    /// Continuously monitored. Real-time behavior analysis and compliance checking.
18    L4,
19}
20
21impl TrustLevel {
22    /// Parse from string (e.g., "L0", "L1", "L2", "L3", "L4").
23    pub fn from_str_repr(s: &str) -> Option<Self> {
24        match s {
25            "L0" => Some(Self::L0),
26            "L1" => Some(Self::L1),
27            "L2" => Some(Self::L2),
28            "L3" => Some(Self::L3),
29            "L4" => Some(Self::L4),
30            _ => None,
31        }
32    }
33
34    /// Convert to string representation.
35    pub fn as_str(&self) -> &'static str {
36        match self {
37            Self::L0 => "L0",
38            Self::L1 => "L1",
39            Self::L2 => "L2",
40            Self::L3 => "L3",
41            Self::L4 => "L4",
42        }
43    }
44
45    /// Human-readable description of the trust level.
46    pub fn description(&self) -> &'static str {
47        match self {
48            Self::L0 => "Self-declared — unverified identity claim",
49            Self::L1 => "Domain-verified — DNS TXT record confirms domain ownership",
50            Self::L2 => "Organization-verified — CA-like verification of controlling entity",
51            Self::L3 => "Audited — third-party security audit completed",
52            Self::L4 => "Continuously monitored — real-time behavior and compliance analysis",
53        }
54    }
55
56    /// Check if this trust level meets a minimum requirement.
57    pub fn meets_minimum(&self, required: TrustLevel) -> bool {
58        *self >= required
59    }
60}
61
62impl fmt::Display for TrustLevel {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        write!(f, "{}", self.as_str())
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_trust_ordering() {
74        assert!(TrustLevel::L0 < TrustLevel::L1);
75        assert!(TrustLevel::L1 < TrustLevel::L2);
76        assert!(TrustLevel::L2 < TrustLevel::L3);
77        assert!(TrustLevel::L3 < TrustLevel::L4);
78    }
79
80    #[test]
81    fn test_meets_minimum() {
82        assert!(TrustLevel::L2.meets_minimum(TrustLevel::L1));
83        assert!(TrustLevel::L1.meets_minimum(TrustLevel::L1));
84        assert!(!TrustLevel::L0.meets_minimum(TrustLevel::L1));
85    }
86
87    #[test]
88    fn test_parse_roundtrip() {
89        for level in [
90            TrustLevel::L0,
91            TrustLevel::L1,
92            TrustLevel::L2,
93            TrustLevel::L3,
94            TrustLevel::L4,
95        ] {
96            let s = level.as_str();
97            let parsed = TrustLevel::from_str_repr(s).unwrap();
98            assert_eq!(parsed, level);
99        }
100    }
101}