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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//! Authentication, sessions, authorization policies, password hashing, and
//! CSRF protection.
//!
//! This module owns the **integration seams** an Arcature application needs to
//! authenticate users safely: Argon2id password hashing, tower-sessions Axum
//! session middleware, double-submit CSRF protection, the `Auth<U>` /
//! `OptionalAuth<U>` / `AuthManager<U>` extractors, the `Session` and `Flash`
//! ergonomics, and the `Policy` authorization seam.
//!
//! # What this module owns
//!
//! * **Argon2id password hashing** with audited salt generation, PHC-formatted
//! stored hashes, parameter configuration, verification, and rehash-on-
//! parameter-change detection ([`PasswordHasher`], [`verify_password`]).
//! * **Secure sessions** over tower-sessions: cookie attributes (name,
//! `SameSite`, `Secure`, `HttpOnly`, path, domain, `Max-Age`, expiry) and a
//! signed cookie jar, built into a [`tower_sessions::SessionManagerLayer`]
//! from a resolved [`SessionConfig`].
//! * **CSRF protection** for cookie-authenticated browser requests via a
//! double-submit token ([`CsrfLayer`], [`CsrfToken`]). Bearer-token APIs and
//! safe-method requests are exempt by design.
//! * **Auth extractors** ([`Auth`], [`OptionalAuth`], [`AuthManager`]) that
//! load the authenticated user from the session + application state.
//! * **Session/Flash ergonomics** ([`Session`], [`Flash`]).
//! * **Authorization** via the [`Policy`] trait and [`Auth::authorize`].
//!
//! # Where each of those lives
//!
//! Every name above is re-exported from `arcature::auth`, so `use
//! arcature::auth::Auth` is the path to write and the submodule is an
//! implementation detail. When you do need the submodule: the extractors are
//! in [`extract`], the handler-facing session API in [`session_api`], the
//! one-time messages in [`flash`], the authorization seam in [`policy`], the
//! cookie/middleware configuration in [`session`], and password hashing in
//! [`password`]. The [`dx`] module is the pre-`0.1.1` spelling of the first
//! four and is deprecated.
//!
//! # What this module does not own
//!
//! It does not own the User model, role/permission/account tables, or any
//! application-specific identity schema -- applications own domain identity.
//! It does not reimplement cryptography (Argon2id, HMAC, SHA-2, and TLS come
//! from RustCrypto, `cookie`, and the certified rustls + aws-lc-rs path). It
//! does not persist sessions to a specific store by default; the application
//! wires any [`tower_sessions::SessionStore`].
//!
//! # Security note -- secrets are never logged
//!
//! Passwords, session signing keys, and tokens are wrapped in
//! [`secrecy`]-backed types whose `Debug`/`Display` never expose the secret
//! and which zeroize on drop. No plaintext password, signing key, or token
//! appears in `Debug`, `Display`, error output, or logs.
/// Deprecated compatibility re-exports; see the module docs for the new homes.
// The security-critical pieces of a sign-in screen -- the ones where the
// obvious implementation leaks something. Behind `auth-flows`, off by
// default. These keep their module rather than being flattened into
// `arcature::auth`: `flows::CredentialChecker` says which layer it belongs
// to, and the layer is the thing a reviewer needs to see.
// Sessions in the application's own database, rather than in a process-local
// `HashMap` that a deploy empties. Behind `session-store-db`, off by default,
// because it brings a table and a migration with it.
// Re-export the certified tower-sessions crate so downstream code targets the
// Arcature-pinned version and reaches the certified `cookie` crate through
// `tower_sessions::cookie`.
pub use tower_sessions;
// Re-export the certified argon2 crate.
pub use argon2;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use PasswordConfig;
pub use ;
pub use ;
pub use ;
pub use ;
// The redirect mapper writes the same session key the `Flash` extractor
// reads, and one spelling of it has to be authoritative.
pub use FLASH_DATA_KEY;
// Re-export the redacting secret wrapper for credential/token holders.
pub use secrecy;
use Serialize;
use DeserializeOwned;
/// The application identity contract.
///
/// Implemented by the application's user type. The framework uses this to
/// store/retrieve the user ID in the session and to type the auth extractors
/// ([`Auth<U>`], [`OptionalAuth<U>`], [`AuthManager<U>`]).
///
/// The application owns identity schema -- this trait does NOT mandate a fixed
/// `User` table, role model, or permission system.
///
/// # Example
///
/// ```
/// use arcature::AuthUser;
///
/// # #[allow(dead_code)]
/// pub struct User {
/// pub id: uuid::Uuid,
/// pub email: String,
/// }
///
/// impl AuthUser for User {
/// type Id = uuid::Uuid;
/// const SESSION_KEY: &'static str = "user_id";
///
/// fn id(&self) -> &uuid::Uuid {
/// &self.id
/// }
/// }
/// # fn main() {}
/// ```