Some checks failed
Run Check Script / check (pull_request) Failing after 1m51s
66 lines
2.4 KiB
Rust
66 lines
2.4 KiB
Rust
//! Shared NATS auth plumbing for fleet processes.
|
|
//!
|
|
//! Two consumers today:
|
|
//!
|
|
//! - **`harmony-fleet-agent`** — reads `[credentials]` from
|
|
//! `/etc/fleet-agent/config.toml`. Per-device Zitadel machine user
|
|
//! with the `device` role.
|
|
//! - **`harmony-fleet-operator`** — reads the same TOML shape from a
|
|
//! single env var (the env var's value is the TOML snippet for the
|
|
//! `[credentials]` table). Singleton machine user with the
|
|
//! `fleet-admin` role.
|
|
//!
|
|
//! Both deserialize into the **same** [`CredentialsSection`], factory
|
|
//! into the **same** [`CredentialSource`], and use the **same**
|
|
//! [`connect_options_with_credentials`] helper to build a NATS client.
|
|
//! The only thing that differs between processes is where the bytes of
|
|
//! the TOML config come from and which Zitadel user signs the
|
|
//! JWT-bearer assertion.
|
|
//!
|
|
//! Adding a new mode (e.g. user JWT from a CLI session) is one new
|
|
//! variant on `CredentialsSection` + `CredentialSource`; everything
|
|
//! else flows through unchanged.
|
|
|
|
mod agent_config;
|
|
mod config;
|
|
mod credentials;
|
|
|
|
pub use agent_config::{AgentConfig, AgentSection, NatsSection, load_config};
|
|
pub use config::CredentialsSection;
|
|
pub use credentials::{
|
|
ASSERTION_LIFETIME_SECS, CachedToken, CredentialSource, MachineKeyFile, NatsCredential,
|
|
TOKEN_REFRESH_LEEWAY_SECS, credential_source_from_config,
|
|
};
|
|
|
|
use std::sync::Arc;
|
|
|
|
/// Build `async_nats::ConnectOptions` wired with the auth callback
|
|
/// that pulls fresh credentials from `creds` on every (re)connect.
|
|
///
|
|
/// Caller chains additional options (`ping_interval`, `event_callback`,
|
|
/// …) before invoking `.connect(urls)`.
|
|
pub fn connect_options_with_credentials(
|
|
creds: Arc<CredentialSource>,
|
|
) -> async_nats::ConnectOptions {
|
|
async_nats::ConnectOptions::with_auth_callback(move |_nonce| {
|
|
let cs = creds.clone();
|
|
async move {
|
|
let cred = cs
|
|
.next_credential()
|
|
.await
|
|
.map_err(|e| async_nats::AuthError::new(format!("credential source: {e}")))?;
|
|
let mut auth = async_nats::Auth::new();
|
|
match cred {
|
|
NatsCredential::UserPass { user, pass } => {
|
|
auth.username = Some(user);
|
|
auth.password = Some(pass);
|
|
}
|
|
NatsCredential::BearerToken(token) => {
|
|
auth.token = Some(token);
|
|
}
|
|
}
|
|
Ok(auth)
|
|
}
|
|
})
|
|
}
|