krabka_audit/operator_keys/error.rs
1//! The startup failures that a bad `[[operator_keys]]` entry raises.
2//!
3//! Every variant here stops the broker at boot. A trust set is all or nothing,
4//! so one unusable entry fails the load. It never shrinks the set that the
5//! later signature checks run against.
6
7use std::{io::Error, path::PathBuf};
8
9/// Failures that stop [`OperatorKeys::load`](crate::operator_keys::OperatorKeys::load),
10/// and with it the broker.
11///
12/// Every variant is a startup error. A key set that a broker cannot load is
13/// never downgraded to a smaller one: a signature checked against a partial
14/// trust set is a signature check that silently does nothing.
15#[derive(Debug, thiserror::Error)]
16#[non_exhaustive]
17pub enum OperatorKeyError {
18 /// A `key_id` or a `principal` is blank. Neither can be matched against a
19 /// signed record, so the entry could never authorize anything.
20 #[error("[[operator_keys]] entry {index} has a blank {field}")]
21 BlankField {
22 /// Zero-based position of the entry in the configured array.
23 index: usize,
24 /// Name of the blank field, `key_id` or `principal`.
25 field: &'static str,
26 },
27 /// The `public_key_path` could not be read.
28 #[error("operator key {key_id:?}: cannot read {}: {source}", path.display())]
29 Unreadable {
30 /// The entry's `key_id`.
31 key_id: String,
32 /// The path that could not be read.
33 path: PathBuf,
34 /// The underlying I/O failure.
35 #[source]
36 source: Error,
37 },
38 /// The file does not hold a raw Ed25519 public key.
39 #[error(
40 "operator key {key_id:?}: {} holds {found} bytes; a raw Ed25519 public key is 32 bytes",
41 path.display()
42 )]
43 Malformed {
44 /// The entry's `key_id`.
45 key_id: String,
46 /// The path that was read.
47 path: PathBuf,
48 /// How many bytes the file holds.
49 found: usize,
50 },
51 /// Two entries share a `key_id`. A signed record names one key, so a
52 /// repeated id makes the key it selects depend on the file order.
53 #[error("duplicate operator key_id {key_id:?}")]
54 DuplicateKeyId {
55 /// The repeated `key_id`.
56 key_id: String,
57 },
58 /// Two entries bind the same principal. The broker checks that a record's
59 /// claimed author is the principal bound to the signing key, and a
60 /// principal with two keys makes that check ambiguous.
61 #[error("operator keys {first:?} and {second:?} are both bound to principal {principal:?}")]
62 DuplicatePrincipal {
63 /// The repeated principal.
64 principal: String,
65 /// The `key_id` that claimed the principal first.
66 first: String,
67 /// The `key_id` that claimed it again.
68 second: String,
69 },
70}