// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. //! Authentication and authorization primitives. //! //! This crate is deliberately I/O-free: it turns bytes into decisions and never //! touches the database or the network. The [`store`](../store/index.html) crate //! persists what these functions produce (password hashes, session-id digests, //! token rows) and the `web`/`api`/`ssh` crates call in at request time. //! //! Four concerns, one per module: //! //! * [`password`] — Argon2id hashing and constant-time verification. A missing //! hash still does the work of a real verify so account existence never leaks //! through timing. //! * [`session`] — opaque session tokens: 32 bytes of OS randomness handed to the //! browser, only their SHA-256 kept server-side. //! * [`token`] — HS256 JSON Web Tokens for the API, minted and verified against //! the instance secret. Revocation is a database concern; this module only //! proves a token is authentic and unexpired. //! * [`scope`] and [`access`] — the authorization vocabulary. [`access::access`] //! is the single, exhaustively tested function every route funnels through. pub mod access; pub mod password; pub mod scope; pub mod session; pub mod token; pub use access::{Access, Permission, Viewer, access}; pub use password::{HashParams, hash_password, verify_password}; pub use scope::{Scope, format_scopes, parse_scopes}; pub use session::{SESSION_TOKEN_BYTES, SessionToken, new_session_token, session_id}; pub use token::{Claims, mint_jwt, new_secret, verify_jwt}; /// Errors produced by the authentication primitives. /// /// Variants stay coarse on purpose: a caller authenticating a request should not /// be able to tell *why* a credential failed (bad signature vs. expired vs. /// malformed), so verification failures collapse into a single /// [`AuthError::InvalidToken`]. #[derive(Debug, thiserror::Error)] pub enum AuthError { /// A password could not be hashed, or a stored hash could not be parsed. /// Carries the library's message; never contains the password itself. #[error("password hashing failed: {0}")] Hash(String), /// A JWT was malformed, carried a bad signature, or had expired. One variant /// for every failure mode so nothing distinguishes them to the caller. #[error("invalid or expired token")] InvalidToken, /// A scope string held a token outside the known set. #[error("unknown scope {0:?}")] UnknownScope(String), }