codlet_core/store/session.rs
1//! Session storage trait (RFC-006).
2
3use std::future::Future;
4
5use crate::hashing::{KeyVersion, LookupKey};
6use crate::secret::{SessionId, SubjectId};
7
8use super::error::StoreError;
9
10/// An active session record returned by validation.
11#[derive(Debug, Clone)]
12pub struct ActiveSessionRecord {
13 /// Opaque session record identifier (not a bearer credential).
14 pub id: SessionId,
15 /// The subject this session authenticates.
16 pub subject: SubjectId,
17 /// Expiry as Unix seconds (UTC).
18 pub expires_at: u64,
19}
20
21/// Parameters for inserting a new session.
22pub struct SessionRecord {
23 /// Store-assigned identifier.
24 pub id: SessionId,
25 /// Domain-separated HMAC of the session secret.
26 pub lookup_key: LookupKey,
27 /// Key version that produced `lookup_key`.
28 pub key_version: KeyVersion,
29 /// The authenticated subject.
30 pub subject: SubjectId,
31 /// Creation time as Unix seconds (UTC).
32 pub created_at: u64,
33 /// Expiry as Unix seconds (UTC).
34 pub expires_at: u64,
35}
36
37/// Session storage (RFC-006).
38///
39/// Sessions are stored by their HMAC lookup key, never by the plaintext secret.
40/// The plaintext lives only in the cookie.
41pub trait SessionStore {
42 /// Look up an active session by HMAC lookup key candidates.
43 ///
44 /// Returns the first record matching any candidate that is not expired and
45 /// not revoked at `now`. Returns `Ok(None)` if no such session exists.
46 fn find_active_session(
47 &self,
48 candidates: &[LookupKey],
49 now: u64,
50 ) -> impl Future<Output = Result<Option<ActiveSessionRecord>, StoreError>>;
51
52 /// Insert a new session record.
53 fn insert_session(&self, record: SessionRecord)
54 -> impl Future<Output = Result<(), StoreError>>;
55
56 /// Revoke a session by its record ID (logout / incident response).
57 /// Revocation is monotonic: a revoked session cannot be unrevoked.
58 fn revoke_session(
59 &self,
60 session_id: &SessionId,
61 now: u64,
62 ) -> impl Future<Output = Result<(), StoreError>>;
63}