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}