brokkr-broker::utils::pak
Rust
Prefixed API Key (PAK) management utilities.
This module provides functionality for creating, verifying, and managing Prefixed API Keys using a singleton controller pattern.
enum PakError
Section titled “enum PakError”pub
Errors returned by the PAK verification helpers.
We expose a small enum (rather than panicking) so the auth middleware can translate parse failures into clean 401s instead of crashing the handler.
Variants
Section titled “Variants”Parse- The supplied string was not a well-formed Prefixed API Key.Controller- Initializing the global PAK controller failed (configuration error).
Functions
Section titled “Functions”fn create_pak_controller
Section titled “fn create_pak_controller”pub
fn create_pak_controller( config: Option<&Settings>,) -> Result<Arc<PrefixedApiKeyController<OsRng, Sha256>>, &'static str>Creates or retrieves the PAK controller.
Parameters:
| Name | Type | Description |
|---|---|---|
config |
Option<&Settings> |
Optional settings for initializing the controller. |
Returns:
Returns a Result containing the Arc-wrapped PAK controller or an error message.
Source
pub fn create_pak_controller( config: Option<&Settings>,) -> Result<Arc<PrefixedApiKeyController<OsRng, Sha256>>, &'static str> { match (PAK_CONTROLLER.get(), config) { (Some(controller), _) => Ok(controller.clone()), (None, Some(cfg)) => { let controller = PAK_CONTROLLER.get_or_init(|| { info!("Initializing PAK_CONTROLLER for the first time"); Arc::new(create_pak_controller_inner(cfg).expect("Failed to create PAK controller")) }); Ok(controller.clone()) } (None, None) => Err("PAK_CONTROLLER not initialized and no config provided"), }}fn create_pak
Section titled “fn create_pak”pub
fn create_pak() -> Result<(String, String), Box<dyn std::error::Error>>Generates a new Prefixed API Key and its hash.
Returns:
Returns a Result containing a tuple of the PAK string and its hash, or an error.
Source
pub fn create_pak() -> Result<(String, String), Box<dyn std::error::Error>> { let controller = create_pak_controller(None)?;
// Generate PAK and hash controller .try_generate_key_and_hash() .map(|(pak, hash)| (pak.to_string(), hash)) .map_err(|e| e.into())}fn verify_pak
Section titled “fn verify_pak”pub
fn verify_pak( pak: String, stored_hash: String,) -> Result<bool, PakError>Verifies a Prefixed API Key against a stored hash.
Returns Ok(true) if the PAK matches the stored hash, Ok(false) if it
is well-formed but does not match, and Err(PakError::Parse) if the
supplied string is not a valid PAK.
Source
pub fn verify_pak(pak: String, stored_hash: String) -> Result<bool, PakError> { let pak = PrefixedApiKey::from_string(pak.as_str()).map_err(|_| PakError::Parse)?; let controller = create_pak_controller(None).map_err(|_| PakError::Controller)?; let computed_hash = controller.long_token_hashed(&pak); // Constant-time comparison: hash equality must not leak match length // through timing (BROKKR-T-0188). Ok(stored_hash .as_bytes() .ct_eq(computed_hash.as_bytes()) .into())}fn generate_pak_hash
Section titled “fn generate_pak_hash”pub
fn generate_pak_hash(pak: String) -> Result<String, PakError>Generates a hash for a given Prefixed API Key.
Returns Err(PakError::Parse) when the string is not a valid PAK so the
caller can respond with 401 instead of panicking.
Source
pub fn generate_pak_hash(pak: String) -> Result<String, PakError> { let pak = PrefixedApiKey::from_string(pak.as_str()).map_err(|_| PakError::Parse)?; let controller = create_pak_controller(None).map_err(|_| PakError::Controller)?; Ok(controller.long_token_hashed(&pak))}