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
//! ECPDS destination authorization plugin for `aviso-server`.
//!
//! This crate decides whether a given user is allowed to read a given
//! ECPDS destination, by consulting one or more ECPDS monitor servers
//! and caching the result. It is consumed by `aviso-server` behind the
//! `ecpds` Cargo feature; deployments that don't need ECPDS auth
//! compile without this crate at all.
//!
//! See `aviso-ecpds/README.md` for an architectural overview, the
//! "ECPDS Destination Authorization" section in the operator
//! documentation for setup, and the "ECPDS Plugin Runbook" for on-call
//! triage.
//!
//! Public surface, at a glance:
//!
//! - [`config::EcpdsConfig`] — serde-deserialised configuration.
//! - [`config::PartialOutagePolicy`] — strict (default) vs any-success
//! merge across multiple ECPDS servers.
//! - [`checker::EcpdsChecker`] — the single facade. `new` is fallible;
//! `check_access` returns [`checker::AccessCheckResult`] (cache
//! outcome plus authorisation result) so the route layer can label
//! hit/miss and fetch metrics on every code path.
//! - [`client::EcpdsError`] / [`client::FetchOutcome`] /
//! [`client::DenyReason`] — domain error type and typed sub-reasons
//! with stable Prometheus label strings.
/// In-process single-flight bounded cache of authorised ECPDS
/// destination lists, keyed by username.
/// The single public facade combining the HTTP client, the cache, and
/// the destination match logic.
/// HTTP client to one or more ECPDS servers, plus the typed error /
/// fetch-outcome / deny-reason types consumed by the route layer.
/// Static configuration for the ECPDS plugin (deserialised from YAML
/// at startup).
pub use EcpdsChecker;
pub use EcpdsError;
use OnceLock;
static SERVICE_NAME_OVERRIDE: = new;
static SERVICE_VERSION_OVERRIDE: = new;
/// Register the parent-process service identity used in this crate's
/// structured tracing events.
///
/// The aviso-ecpds crate emits its own `auth.ecpds.fetch.*` and
/// `auth.ecpds.cache.*` tracing events. To keep log routing and
/// dashboards consistent with events emitted from `aviso-server`
/// itself, the parent crate calls this once at startup with its own
/// `SERVICE_NAME` and `SERVICE_VERSION` so subcrate events identify
/// under the same service identity. Subsequent calls are no-ops
/// (`OnceLock`).
///
/// When unset (e.g. running the subcrate's own tests in isolation),
/// events fall back to the subcrate's own `CARGO_PKG_NAME` /
/// `CARGO_PKG_VERSION`.
pub
pub