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
101
102
103
104
//! Boot-time security invariants.
//!
//! A service calls these helpers once, during startup, before opening its
//! listening socket. They panic or return `Err` on misconfiguration so the
//! service fails closed rather than serving requests with a dev identity
//! source active in production.
use fmt;
/// Production-mode misconfiguration — a dev-mode identity source is
/// registered while `APP_ENV` is set to `"production"`.
///
/// Returned by [`assert_no_dev_identity_in_production`]. Implements
/// [`std::error::Error`] + [`fmt::Display`] so services can log it or
/// convert it to a panic message.
///
/// # Examples
///
/// ```
/// use secure_identity::boot::{
/// assert_no_dev_identity_in_production, ProductionModeViolation,
/// };
///
/// let err: ProductionModeViolation =
/// assert_no_dev_identity_in_production("production", true).unwrap_err();
/// assert!(err.to_string().contains("production"));
/// ```
/// Asserts no dev-mode identity source is registered when `app_env ==
/// "production"`.
///
/// Call this at service boot (before the listener starts) so
/// misconfigurations fail closed. The caller is responsible for knowing
/// whether any dev-mode identity source is registered in the validator
/// chain — pass `true` if any of:
///
/// - `DevAuthenticator` (from [`crate::dev`]) is registered,
/// - a `DevBearerSource` fixture is active,
/// - any other component that bypasses real credential validation is
/// wired into the request path.
///
/// # Errors
///
/// Returns [`ProductionModeViolation`] if `app_env == "production"` and
/// `has_dev_identity_source == true`.
///
/// # Examples
///
/// ```
/// use secure_identity::boot::assert_no_dev_identity_in_production;
///
/// // Staging with dev identity is fine.
/// assert!(assert_no_dev_identity_in_production("staging", true).is_ok());
///
/// // Production without dev identity is fine.
/// assert!(assert_no_dev_identity_in_production("production", false).is_ok());
///
/// // Production WITH dev identity is a violation.
/// assert!(assert_no_dev_identity_in_production("production", true).is_err());
/// ```
///
/// Typical boot wiring:
///
/// ```no_run
/// use secure_identity::boot::assert_no_dev_identity_in_production;
///
/// let app_env = std::env::var("APP_ENV").unwrap_or_default();
/// let has_dev = cfg!(feature = "dev"); // or your own detection
///
/// if let Err(violation) = assert_no_dev_identity_in_production(&app_env, has_dev) {
/// panic!("{violation}");
/// }
/// ```