1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! Break-glass proposal records, replicated through the raft quorum with
//! `MetadataRecord::V1BreakGlassProposal` and
//! `V1DeleteBreakGlassProposal`.
//!
//! A break-glass workflow needs two different people to agree before the
//! broker does a privileged operation. An approved proposal is a standing
//! authorization for a bounded window, and not a field on the request it
//! authorizes, so no Kafka wire message changes. An operator gets the
//! approval out of band, then runs the ordinary tool, and the broker reads
//! the proposal out of the metadata image.
//!
//! The records stay pure data. The approver set, the distinct-principal rule,
//! and the signature checks live in `krabka-broker`. The one rule this crate
//! enforces is in
//! [`MetadataImage::validate`](crate::MetadataImage::validate): an incoming
//! approval list must extend the stored one, so two concurrent approvals
//! cannot overwrite each other.
use ;
use Uuid;
/// The privileged transitions that a break-glass proposal can authorize.
///
/// Each one can lose committed data, or can lift the protection that stops
/// another one from losing committed data.
/// One approval on a proposal.
///
/// The broker checks that the principal is in the configured approver set,
/// that it is not the proposer, and that it is not already in the list.
/// One break-glass proposal, keyed by [`Self::proposal_id`].
///
/// The record is authoritative for that id: a later record with the same id
/// replaces the earlier one, which is how an approval and a consumption are
/// both written. `V1DeleteBreakGlassProposal` removes the entry, and the
/// expiry sweep emits it.