Skip to main content

kovra_core/
error.rs

1//! Error types for `kovra-core`.
2
3use thiserror::Error;
4
5/// Errors produced by the core model, coordinate parsing, and crypto-at-rest.
6///
7/// Crypto failures are deliberately opaque (no inner detail) so they cannot act
8/// as an oracle, and no variant ever carries secret material (I12).
9#[derive(Debug, Error)]
10pub enum CoreError {
11    /// A `secret:` coordinate URI was malformed (wrong segment count, illegal
12    /// interpolation, empty segment, or bad scope authority).
13    #[error("invalid coordinate URI: {0}")]
14    InvalidCoordinate(String),
15
16    /// AEAD sealing/opening failed: wrong key, corrupted record, or bad tag.
17    #[error("crypto operation failed")]
18    Crypto,
19
20    /// (De)serialization of a record payload failed.
21    #[error("record serialization failed: {0}")]
22    Serialization(String),
23
24    /// A filesystem operation against the vault store failed. Carries an
25    /// operation/context string only — never a secret value (I12).
26    #[error("vault I/O failed: {0}")]
27    Io(String),
28
29    /// Master-key acquisition via the keyring (or the Argon2 fallback) failed.
30    /// Carries no key material (I12).
31    #[error("keyring operation failed: {0}")]
32    Keyring(String),
33
34    /// The metadata index (redb) could not be opened, written, or rebuilt. The
35    /// index is a rebuildable cache, so this is recoverable by a rebuild and is
36    /// never data loss (ADR-0001 §A.6).
37    #[error("metadata index failed: {0}")]
38    Index(String),
39
40    /// The requested coordinate cannot be addressed by the store: it carries an
41    /// unresolved `${ENV}` placeholder (placeholders resolve at L4, not here).
42    #[error("coordinate is not storable: {0}")]
43    NotStorable(String),
44
45    /// A policy operation could not be carried out (e.g. building a decision
46    /// from malformed inputs). Carries no secret material (I12).
47    #[error("policy error: {0}")]
48    Policy(String),
49
50    /// The audit log could not be written. Carries no secret material (I12).
51    #[error("audit error: {0}")]
52    Audit(String),
53
54    /// A `.env.refs` line was malformed, or a value could not be resolved
55    /// (unresolved placeholder, prod fallback, missing passthrough, …). Carries
56    /// no secret material (I12).
57    #[error("env-refs error: {0}")]
58    EnvRefs(String),
59
60    /// An asymmetric-key operation failed: key generation, parsing an OpenSSH
61    /// key, signing, verifying, encrypting, decrypting, or loading into the
62    /// ssh-agent. Carries an operation description only — never key material
63    /// (I12). Sign/verify/decrypt failures are deliberately coarse so they
64    /// cannot act as an oracle.
65    #[error("keypair operation failed: {0}")]
66    Keypair(String),
67
68    /// A TOTP operation failed: a malformed base32 seed, an `otpauth://` URI
69    /// that could not be parsed, or an out-of-range parameter (digits/period).
70    /// Carries an operation description only — never the seed bytes (I12).
71    #[error("totp operation failed: {0}")]
72    Totp(String),
73
74    /// An external provider failed to materialize a reference: a malformed
75    /// reference URI, an unsupported scheme, the provider CLI being absent or
76    /// unauthenticated, the secret not existing, or a timeout (§6). Carries an
77    /// operation/diagnostic description only — never the materialized value
78    /// (I12); failures are deliberately specific so a misconfiguration is clear
79    /// rather than a silent empty value.
80    #[error("provider error: {0}")]
81    Provider(String),
82
83    /// An encrypted-package or access-token operation failed (L7, §7): a
84    /// foreign/garbage package frame, an expired package/token, a `prod` secret
85    /// refused at packaging (I4a) or under a token (I4b), or a token that does
86    /// not match its package. Carries a coordinate/diagnostic description only —
87    /// never a value, and crypto failures are deliberately opaque (I12).
88    #[error("package error: {0}")]
89    Package(String),
90
91    /// A removable-media format operation failed or was refused (KOV-40): the
92    /// target is not external/ejectable (the hard safety rail), the wipe was
93    /// denied/timed out at the broker, or the OS formatter errored. Carries a
94    /// device-node/diagnostic description only — never a secret value (I12).
95    #[error("format error: {0}")]
96    Format(String),
97}