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
//! Admin elevation — the one place that answers "is this caller carrying a
//! live step-up right now?", and the one refusal every admin-conferring path
//! emits when they are not.
//!
//! ## Why this is its own module
//!
//! VTI-OPS-050/051 put a **fresh reauthentication** in front of conferring
//! administrative authority. Both halves of the answer live here so they cannot
//! drift apart:
//!
//! - [`verified`] resolves the elevation from the caller's **live session**,
//! which is the only thing that can be trusted to say so. A route handler
//! passing a boolean is not evidence; it is the handler's opinion.
//! - [`required`] is the refusal, and it names the ceremony the operator has to
//! run, because an operator reading "forbidden" has no way to guess that the
//! fix is a passkey.
//!
//! ## Where each gate lives
//!
//! - `acl/change-role` is a role **transition**, so it runs the role-change
//! ceremony, and its gate is the host invariant
//! [`Invariant::StepUpForAdmin`](crate::ceremony::Invariant). [`verified`]
//! supplies the fact it reads.
//! - `acl/grant` and `acl/update` write an entry rather than moving one. Their
//! gate is bound to the operation ([`crate::acl::bound_step_up`]) and asked
//! only when the write **widens** administrative authority
//! ([`crate::acl::AdminAuthority::widens_from`]) — so a rewrite that confers
//! nothing new (the console's label edit) does not demand a passkey.
//!
//! ## A role is a ceiling, and that matters here
//!
//! A VTC entry holds an explicit capability set beneath its administrative
//! role (`vtc-admin-roles.md` §6, VTI-ACL-030): the role is a ceiling, never
//! the grant. So a gate that read only the role would over-trust a narrowed
//! entry, and a widening that never touches the role — `capabilities: listed`
//! back to `ceiling`, a qualifier widened, approve authority added — is a
//! grant like any other. That is why the widening test compares what the entry
//! can exercise and approve before and after, never the role alone.
use AuthClaims;
use AppError;
use KeyspaceHandle;
/// Whether `actor`'s session carries a live step-up elevation **now**.
///
/// Reads the session row rather than the bearer token: the elevation is a
/// bounded window stamped on the session by
/// `auth/passkey/login/finish/0.2` with `purpose: stepUp`, and a token minted
/// before it — or long after it lapsed — says nothing about it.
///
/// A missing session, an expired window and a session that was never elevated
/// are all "not elevated". Failing closed is the only safe reading: the fact
/// this produces is what stands between an admin session and conferring admin.
pub async
/// The refusal for an admin-conferring call with no live elevation.
///
/// [`AppError::StepUpRequired`] renders as `403 step_up_required`, which is
/// the signal the admin console turns into a passkey prompt; the message names
/// the ceremony for every other caller.