Skip to content

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.

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.

  • Parse - The supplied string was not a well-formed Prefixed API Key.
  • Controller - Initializing the global PAK controller failed (configuration error).

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"),
}
}

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())
}

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())
}

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))
}