brokkr-broker::utils
Rust
Utility functions and structures for the Brokkr broker.
This module contains various helper functions and structures used throughout the broker, including admin key management and shutdown procedures.
Structs
Section titled “Structs”struct AdminKey
Section titled “struct AdminKey”pub
Derives: Queryable, Selectable, Identifiable, AsChangeset, Debug, Clone
Represents an admin key in the database.
Fields
Section titled “Fields”| Name | Type | Description |
|---|---|---|
id |
Uuid |
|
created_at |
chrono::DateTime<Utc> |
|
updated_at |
chrono::DateTime<Utc> |
|
pak_hash |
String |
struct NewAdminKey
Section titled “struct NewAdminKey”pub
Derives: Insertable
Represents a new admin key to be inserted into the database.
Fields
Section titled “Fields”| Name | Type | Description |
|---|---|---|
pak_hash |
String |
struct DefaultAdminPakStatus
Section titled “struct DefaultAdminPakStatus”pub
Derives: Debug, Clone, Copy, PartialEq, Eq
Which admin credential sources still carry the shipped default hash.
The two are tracked separately because they have different causes and
different fixes. configured is the live config value; stored is what is
actually in admin_role.pak_hash — and those can disagree, because
upsert_admin only runs on first startup (or an explicit rotate admin).
An install that first booted with the default and later had
BROKKR__BROKER__PAK_HASH set keeps accepting the public PAK until the
admin row is rotated, which is the case a config-only check would miss.
Fields
Section titled “Fields”| Name | Type | Description |
|---|---|---|
configured |
bool |
The configured broker.pak_hash is the shipped default. |
stored |
bool |
The admin hash stored in the database is the shipped default. |
Methods
Section titled “Methods”in_use
Section titled “in_use”pub
fn in_use(&self) -> boolTrue when the publicly-known PAK is accepted as admin by this broker.
Source
pub fn in_use(&self) -> bool { self.configured || self.stored }enum AdminPakOutcome
Section titled “enum AdminPakOutcome”pub
What upsert_admin actually did.
The two branches look identical from the outside — both end with a hash on
admin_role and the admin generator — but only one produces a new
credential. rotate admin reports “rotated successfully” for both unless it
is told them apart, which is misleading on the branch that mints nothing
(BROKKR-T-0317).
Variants
Section titled “Variants”Minted- No hash was configured, so a fresh PAK was minted. The plaintext is returned and written toBOOTSTRAP_KEY_FILE; it cannot be recovered from the hash afterwards.ReappliedConfigured-broker.pak_hashwas set, so it was validated and re-applied verbatim. No credential was created and whatever PAK matches that hash keeps working — including, on a default install, the publicly-known one.
Functions
Section titled “Functions”fn shutdown
Section titled “fn shutdown”pub
async fn shutdown(shutdown_rx: oneshot::Receiver<()>)Handles the shutdown process for the broker.
This function waits for a shutdown signal and then performs cleanup tasks.
Source
pub async fn shutdown(shutdown_rx: oneshot::Receiver<()>) { let _ = shutdown_rx.await; // Remove the bootstrap key file dropped by `upsert_admin` on first startup. let _ = fs::remove_file(BOOTSTRAP_KEY_FILE);}fn first_startup
Section titled “fn first_startup”pub
fn first_startup( conn: &mut PgConnection, config: &Settings,) -> Result<(), Box<dyn std::error::Error>>Performs first-time startup operations.
This function is called when the broker starts for the first time and sets up the initial admin key.
Source
pub fn first_startup( conn: &mut PgConnection, config: &Settings,) -> Result<(), Box<dyn std::error::Error>> { // `serve` deliberately does not surface the PAK on stdout: it is a // long-running process whose output is a log stream, and a secret written // there would persist in `kubectl logs` for the pod's lifetime. The // bootstrap key file remains that path's channel. upsert_admin(conn, config).map(|_| ())}fn upsert_admin
Section titled “fn upsert_admin”pub
fn upsert_admin( conn: &mut PgConnection, config: &Settings,) -> Result<AdminPakOutcome, Box<dyn std::error::Error>>Updates or inserts the admin key and related generator.
This function creates or updates the admin key in the database, creates or updates the associated admin generator, and writes the PAK to a temporary file.
Source
pub fn upsert_admin( conn: &mut PgConnection, config: &Settings,) -> Result<AdminPakOutcome, Box<dyn std::error::Error>> { let outcome = match &config.broker.pak_hash { Some(hash) if !hash.is_empty() => { // Validate the provided hash if !validate_pak_hash(hash) { return Err("Invalid PAK hash provided in configuration".into()); } AdminPakOutcome::ReappliedConfigured { hash: hash.clone() } } _ => { // Generate new PAK and hash let (pak, hash) = create_pak()?;
// Write PAK to temporary file. Retained as the channel for // `serve`'s first startup, which cannot print secrets; `rotate // admin` also returns the plaintext so it can be shown directly. info!("Writing PAK to temporary file"); let key_path = Path::new(BOOTSTRAP_KEY_FILE); fs::create_dir_all(key_path.parent().unwrap())?; fs::write(key_path, &pak)?;
AdminPakOutcome::Minted { pak, hash } } };
let pak_hash = match &outcome { AdminPakOutcome::Minted { hash, .. } => hash.clone(), AdminPakOutcome::ReappliedConfigured { hash } => hash.clone(), };
// Update or insert admin key let existing_admin_key = admin_role::table .select(admin_role::id) .first::<Uuid>(conn) .optional()?;
match existing_admin_key { Some(id) => { diesel::update(admin_role::table.find(id)) .set(admin_role::pak_hash.eq(&pak_hash)) .execute(conn)?; } None => { diesel::insert_into(admin_role::table) .values(&NewAdminKey { pak_hash: pak_hash.clone(), }) .execute(conn)?; } }
// Update or insert admin generator use brokkr_models::schema::generators; let existing_admin_generator = generators::table .filter(generators::name.eq("admin-generator")) .select(generators::id) .first::<Uuid>(conn) .optional()?;
match existing_admin_generator { Some(id) => { diesel::update(generators::table.find(id)) .set(( generators::pak_hash.eq(&pak_hash), generators::description.eq("Linked to Admin PAK"), )) .execute(conn)?; } None => { diesel::insert_into(generators::table) .values(( generators::name.eq("admin-generator"), generators::description.eq("Linked to Admin PAK"), generators::pak_hash.eq(&pak_hash), )) .execute(conn)?; } }
Ok(outcome)}fn detect_default_admin_pak_hash
Section titled “fn detect_default_admin_pak_hash”pub
fn detect_default_admin_pak_hash( configured: Option<&str>, stored: Option<&str>,) -> DefaultAdminPakStatusCompares the effective admin credential against the shipped default.
Pure and exact: byte equality against DEFAULT_ADMIN_PAK_HASH, no
heuristics, no I/O. serve binds a port and installs process-global state,
so the decision lives here where it can be tested directly.
Parameters:
| Name | Type | Description |
|---|---|---|
configured |
Option<&str> |
config.broker.pak_hash after the full config layering. |
stored |
Option<&str> |
admin_role.pak_hash as currently persisted, if the row exists. |
Source
pub fn detect_default_admin_pak_hash( configured: Option<&str>, stored: Option<&str>,) -> DefaultAdminPakStatus { DefaultAdminPakStatus { configured: configured == Some(DEFAULT_ADMIN_PAK_HASH), stored: stored == Some(DEFAULT_ADMIN_PAK_HASH), }}fn stored_admin_pak_hash
Section titled “fn stored_admin_pak_hash”pub
fn stored_admin_pak_hash( conn: &mut PgConnection,) -> QueryResult<Option<String>>Reads the persisted admin PAK hash, if the admin role has been provisioned.
Runs against whatever schema the connection’s search_path selects, so on a
multi-tenant install it reports the tenant the broker is actually serving.
Source
pub fn stored_admin_pak_hash(conn: &mut PgConnection) -> QueryResult<Option<String>> { admin_role::table .select(admin_role::pak_hash) .first::<String>(conn) .optional()}fn report_default_admin_pak_hash
Section titled “fn report_default_admin_pak_hash”pub
fn report_default_admin_pak_hash(status: &DefaultAdminPakStatus)Logs the default-admin-PAK banner (if applicable) and publishes brokkr_default_admin_pak_hash_in_use.
Always sets the gauge, including to 0, so the metric is present and
alertable on a correctly-configured broker rather than only appearing on a
broken one.
Source
pub fn report_default_admin_pak_hash(status: &DefaultAdminPakStatus) { DEFAULT_ADMIN_PAK_HASH_IN_USE.set(i64::from(status.in_use()));
match default_admin_pak_warning(status) { Some(banner) => warn!("{}", banner), None => info!("Admin PAK hash is not the shipped default"), }}fn start_default_admin_pak_reminder_task
Section titled “fn start_default_admin_pak_reminder_task”pub
fn start_default_admin_pak_reminder_task(status: DefaultAdminPakStatus)Spawns the hourly re-warning task described on DEFAULT_ADMIN_PAK_REMINDER_INTERVAL. No-op when the default is not in use, so a correctly-configured broker carries no extra task.
Must be called from within a Tokio runtime.
Source
pub fn start_default_admin_pak_reminder_task(status: DefaultAdminPakStatus) { let Some(banner) = default_admin_pak_warning(&status) else { return; };
tokio::spawn(async move { loop { tokio::time::sleep(DEFAULT_ADMIN_PAK_REMINDER_INTERVAL).await; warn!("{}", banner); } });}