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
//! Enriched-identity resolution: a request-scoped `sub → DB → identity` mapping.
//!
//! Resolved once per request, cached, and fail-closed, it feeds both
//! read-scoping (session variables / injected params) and verified
//! sender-identity (`send_email`).
//!
//! # Structure
//!
//! - `query` — safe named-parameter binding (`$name` → positional `$N`, values bound out-of-band,
//! never interpolated). Ported verbatim from #242, with the missing-param error refined to a
//! structured `MissingParam`.
//! - `cache` — the identity cache (DESIGN §6): keyed on the bound-`$param` tuple, positive and
//! negative TTL, `flush(sub)`.
//! - `failure` — the `IdentityResolution` model (DESIGN §5): `Resolved` / `Denied` / `Unavailable`,
//! fail-closed at source.
//! - `resolver` — the shared `IdentityResolver`: bind → cache → fetch (≤2 rows) → classify → cache,
//! with server-side denial logging.
//!
//! The read-path consumer (`apply::enrich_security_context`) is wired into the
//! `/graphql` handler, and the cache flush surface (`admin::identity_admin_router`)
//! into the admin API. The DB-backed sender is the one seam whose consumer lands
//! elsewhere (the hardening-train `send_email` op), so it carries a scoped
//! `dead_code` allow at its definition rather than a blanket module allow.
//!
//! Enrichment requires an authenticated subject, so the whole module is gated on
//! the `auth` feature (mirroring the `enrichment_pool` the resolver uses).
pub
pub
pub
pub
pub
pub
pub
pub use identity_admin_router;
pub use ;
use ;
pub use ;
/// Whether the compiled schema declares any consumer of enriched identity — a
/// `SessionVariableSource::Enrichment` or an `InjectedParamSource::Enrichment`.
///
/// Used only to decide whether an enabled-but-unused enrichment profile warrants
/// a loud startup warning (DESIGN §7). The per-request fail-closed boundary
/// itself never depends on this scan — that would reintroduce the exact
/// declaration-conditional silent-skip the design fights.
pub