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
use crateSecurityContext;
use Error as PostcardError;
use Error;
/// Format version, written as the first byte of every encoded blob.
///
/// [`decode_bin`] accepts this version and no other, so producer and consumer
/// must agree exactly — there is no backward-compatible read path.
///
/// **Bump this whenever [`SecurityContext`]'s serialized field list changes.**
/// postcard is positional and carries no field names, so adding, removing or
/// reordering a field silently changes the layout: an older decoder would then
/// read the new bytes as whatever its own field order says, rather than
/// rejecting them. The version byte is the only thing that turns that into a
/// clean `UnsupportedVersion` error, and nothing derives it automatically.
pub const SECCTX_BIN_VERSION: u8 = 1;
/// Why a [`SecurityContext`] could not be encoded.
/// Why a blob could not be decoded into a [`SecurityContext`].
/// Encode `SecurityContext` into a versioned binary blob using `postcard`.
/// This does not do any signing or encryption, it is just a transport format.
///
/// # Errors
/// Returns `SecCtxEncodeError` if postcard serialization fails.
/// Decode `SecurityContext` from a versioned binary blob produced by `encode_bin()`.
///
/// # This does not authenticate anything
///
/// The blob is neither signed nor encrypted, and the only check here is the
/// version byte. Whoever produced these bytes chose the subject, the tenant and
/// the scopes in the context that comes back — so calling this on input a peer
/// supplied is letting that peer pick its own identity.
///
/// The precondition is that the peer was **already authenticated** and the
/// transport is trusted: in-process, or a link where the sender was validated
/// by other means. Never call it on inbound metadata from an unauthenticated
/// caller, and strip `x-secctx-bin` at any boundary where callers are not
/// already authenticated — a header from outside must never reach this
/// function. ADR `cpt-cf-adr-two-plane-auth` keeps cross-process calls off this
/// path entirely: they carry a re-validated bearer token instead.
///
/// # Errors
/// Returns `SecCtxDecodeError::Empty` if the input is empty.
/// Returns `SecCtxDecodeError::UnsupportedVersion` if the version byte is not supported.
/// Returns `SecCtxDecodeError::Postcard` if postcard deserialization fails.