codlet_core/lib.rs
1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4//! # codlet-core
5//!
6//! Runtime-neutral authentication primitives. This crate contains pure types,
7//! policy objects, cryptographic lookup-key derivation, lifecycle state
8//! machines, storage traits, and audit events. It deliberately contains no web
9//! framework, database, or async-executor dependencies (RFC-002).
10//!
11//! ## Boundary
12//!
13//! codlet authenticates a subject. The host application authorizes that
14//! subject (RFC-001). Nothing in this crate decides community membership,
15//! roles, permissions, or resource access.
16//!
17//! ## Status
18//!
19//! This release completes the M3 primitive layer:
20//!
21//! - [`code`] — code policy, generation, normalization, validation (RFC-003)
22//! - [`hashing`] — HMAC lookup-key derivation, key providers, domain
23//! separation, key versioning (RFC-004)
24//! - [`rng`] — fail-closed randomness abstraction (RFC-020)
25//! - [`secret`] — redacted secret newtypes and opaque IDs (RFC-019 foundation)
26//! - [`clock`] — `Clock` trait for testable time (RFC-020)
27//! - [`state`] — pure lifecycle classifiers: claim, session, form-token
28//! consume (RFC-005/006/007)
29//! - [`store`] — `CodeStore`, `SessionStore`, `FormTokenStore`,
30//! `RateLimitStore` traits (RFC-005/006/007/008)
31//! - [`cookie`] — secure cookie policy and builder (RFC-006)
32//! - [`audit`] — `CodeAuthEvent` vocabulary and `AuditSink` trait (RFC-012)
33//! - [`error`] — two-layer error model: internal causes + public-safe
34//! failures (RFC-012/021)
35//! - `mem` — in-memory stores (`test-utils` feature only, RFC-011/008)
36
37/// The codlet wire/format version embedded in domain-separated HMAC inputs.
38///
39/// Bumping this is a breaking change to every stored lookup key and MUST be
40/// accompanied by a key-version migration (RFC-004).
41pub const FORMAT_VERSION: &str = "codlet/v1";
42
43pub mod audit;
44pub mod auth;
45pub mod clock;
46pub mod code;
47pub mod cookie;
48pub mod error;
49pub mod hashing;
50pub mod rng;
51pub mod secret;
52pub mod state;
53pub mod store;
54
55/// In-memory store implementations for tests and local development.
56///
57/// **Not for production.** Gated behind the `test-utils` feature.
58#[cfg(any(test, feature = "test-utils"))]
59pub mod mem;
60
61// Convenience re-exports for the most common types.
62pub use audit::{AuditSink, CodeAuthEvent, NoopAuditSink};
63pub use auth::{
64 CodeAuth, FormTokenError, FormTokenManager, IssuedSession, NoRateLimit, RedeemError,
65 RedeemSuccess, SessionError, SessionManager,
66};
67pub use clock::{Clock, SystemClock};
68pub use code::{Alphabet, CodePolicy, generate_code, normalize, validate_code_input};
69pub use cookie::{CookiePolicy, CookieProfile, SameSitePolicy};
70pub use error::{
71 CodeInputError, KeyError, PolicyError, PublicFormError, PublicRedemptionError,
72 PublicSessionError, RandomError, RedemptionFailReason,
73};
74pub use hashing::{
75 HmacKeyRef, KeyProvider, KeyVersion, LookupKey, SecretDomain, SecretHasher, StaticKeyProvider,
76};
77pub use rng::{RandomSource, SystemRandom};
78pub use secret::{
79 CodeId, FormTokenSecret, NormalizedCode, PlainCode, Purpose, ScopeKey, SecretString, SessionId,
80 SessionSecret, SubjectId,
81};
82pub use state::{
83 ClaimOutcome, SessionValidationOutcome, TokenConsumeOutcome, classify_claim, classify_session,
84 classify_token_consume,
85};
86pub use store::{
87 error::{PublicAuthError, StoreError},
88 ratelimit::{
89 RateLimitKey, RateLimitOutcome, RateLimitPolicy, RateLimitStore, RateLimitUnavailable,
90 },
91 token::TokenSubject,
92};
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn format_version_is_stable() {
100 // Guard against an accidental format bump. Changing this string is a
101 // breaking change requiring a key-version migration (RFC-004).
102 assert_eq!(FORMAT_VERSION, "codlet/v1");
103 }
104}