Skip to main content

blindplane_access/
error.rs

1//! Access-layer errors.
2
3/// A structural, trust, policy, or cryptographic access failure.
4#[derive(Clone, Debug, Eq, PartialEq)]
5pub enum AccessError {
6    /// The input ended before the object did.
7    Truncated,
8    /// The object has bytes after its canonical end.
9    TrailingBytes,
10    /// The object uses an unsupported version.
11    UnsupportedVersion(u16),
12    /// The encoded object tag does not match the requested type.
13    WrongObjectType,
14    /// An identifier is empty or exceeds the configured bound.
15    InvalidIdentifier,
16    /// An encoded identifier is not UTF-8.
17    InvalidUtf8,
18    /// A length exceeds the configured bound.
19    LengthLimit(usize),
20    /// An epoch or monotonic revision is zero or otherwise invalid.
21    InvalidEpoch,
22    /// A key does not match its domain-separated identifier or is unusable.
23    InvalidKeyIdentity,
24    /// Re-encoding did not reproduce the original bytes.
25    NonCanonicalEncoding,
26    /// A capability kind/name pair appears more than once.
27    DuplicateRule,
28    /// A signature is malformed or does not verify.
29    InvalidSignature,
30    /// The object was not issued by the caller's pinned issuer.
31    UntrustedIssuer,
32    /// The object belongs to a different tenant, subject, or scope.
33    SubjectMismatch,
34    /// The signed object is not active yet.
35    NotYetValid,
36    /// The signed object has expired.
37    Expired,
38    /// A monotonic policy or revocation revision is below the required floor.
39    StaleRevision,
40    /// An authorization or key epoch has been revoked.
41    Revoked,
42    /// A grant contains no permissions or unknown permission bits.
43    InvalidPermissions,
44    /// HPKE sealing or opening failed without exposing a decryption oracle.
45    CryptographicFailure,
46}
47
48impl core::fmt::Display for AccessError {
49    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50        match self {
51            Self::Truncated => f.write_str("access object is truncated"),
52            Self::TrailingBytes => f.write_str("access object has trailing bytes"),
53            Self::UnsupportedVersion(version) => {
54                write!(f, "unsupported access object version {version}")
55            }
56            Self::WrongObjectType => f.write_str("wrong access object type"),
57            Self::InvalidIdentifier => f.write_str("invalid access identifier"),
58            Self::InvalidUtf8 => f.write_str("access identifier is not UTF-8"),
59            Self::LengthLimit(length) => write!(f, "access length {length} exceeds its limit"),
60            Self::InvalidEpoch => f.write_str("invalid access epoch or revision"),
61            Self::InvalidKeyIdentity => f.write_str("invalid access key identity"),
62            Self::NonCanonicalEncoding => f.write_str("non-canonical access object encoding"),
63            Self::DuplicateRule => f.write_str("duplicate capability rule"),
64            Self::InvalidSignature => f.write_str("invalid access object signature"),
65            Self::UntrustedIssuer => f.write_str("access object issuer is not trusted"),
66            Self::SubjectMismatch => {
67                f.write_str("access object tenant, subject, or scope does not match")
68            }
69            Self::NotYetValid => f.write_str("access object is not active yet"),
70            Self::Expired => f.write_str("access object has expired"),
71            Self::StaleRevision => f.write_str("access object revision is stale"),
72            Self::Revoked => f.write_str("access object epoch has been revoked"),
73            Self::InvalidPermissions => f.write_str("invalid access permissions"),
74            Self::CryptographicFailure => f.write_str("access cryptographic operation failed"),
75        }
76    }
77}
78
79impl std::error::Error for AccessError {}