pas_external/session_liveness/mod.rs
1//! Session liveness — two complementary axes.
2//!
3//! # Per-request session-row check ([`SessionLiveness`])
4//!
5//! Phase 11.Z 0.10.0 (RFC_2026-05-08 §4.2 lock). The verifier-side L2
6//! port: "is the bearer token's session row still alive in the
7//! consumer's own DB?" Wired into
8//! [`crate::JwtVerifier::with_session_liveness`]. Always available
9//! (no feature gate) — the port itself has no AES / OAuth deps.
10//!
11//! # Periodic PAS refresh-token check (`feature = "session-liveness"`)
12//!
13//! When a consumer persists PAS `refresh_token`s server-side and treats
14//! PAS as the single source of truth for session validity, the code path
15//! is always the same:
16//!
17//! 1. Encrypt the `refresh_token` at rest.
18//! 2. Periodically ask PAS "is this session still live?" via
19//! [`attempt_liveness_refresh`].
20//! 3. Distinguish a *revoked* session from a *transient* failure.
21//!
22//! This half ships behind `feature = "session-liveness"`:
23//!
24//! - [`TokenCipher`] — AES-256-GCM wrapper for at-rest encryption.
25//! - [`LivenessOutcome`] — classification of a single liveness attempt.
26//! - [`attempt_liveness_refresh`] — the decrypt → call PAS →
27//! re-encrypt sequence wrapped as one call. Generic over
28//! `P: PasAuthPort`.
29//!
30//! See `pas_external::pas_port` for the underlying port.
31//!
32//! Both halves answer "is this user's session valid?" at different
33//! layers and cadences — one shared umbrella module keeps the surface
34//! coherent. The 0.10.0 lookup port has no `aes-gcm` / `oauth`
35//! transitive deps, so consumers can use L2 row-checks without pulling
36//! the AES wrapper.
37
38// `SessionLiveness` + `SessionLivenessError` — the per-request L2 row
39// liveness port — are migrated to `ppoppo-sdk-core::session_liveness`
40// in Phase A so multiple SDK crates and 1st-party services consume one
41// shared trait. Re-exported here so `pas_external::session_liveness::*`
42// + `pas_external::SessionLiveness` keep the same surface.
43pub use ::ppoppo_sdk_core::session_liveness::{SessionLiveness, SessionLivenessError};
44
45#[cfg(feature = "session-liveness")]
46mod cipher;
47#[cfg(feature = "session-liveness")]
48mod liveness;
49
50#[cfg(feature = "session-liveness")]
51pub use cipher::{CipherError, EncryptedRefreshToken, TokenCipher};
52#[cfg(feature = "session-liveness")]
53pub use liveness::{
54 LivenessFailure, LivenessOutcome, RevokeCause, TransientCause, attempt_liveness_refresh,
55};