aster_forge_auth/provider.rs
1//! Explicit initialization of the upstream process-wide JWT crypto provider.
2
3use crate::{AuthError, Result};
4use std::sync::atomic::{AtomicBool, Ordering};
5
6// Only a successful explicit installation makes Forge JWT operations available. The upstream
7// provider is immutable once installed; this flag neither selects nor replaces that provider.
8static INITIALIZED: AtomicBool = AtomicBool::new(false);
9
10/// Installs the backend selected by this crate's Cargo features for the entire process.
11///
12/// Call exactly once from the product composition root before starting workers or making any
13/// JWT calls, including direct `jsonwebtoken` calls. Features are additive: another dependency
14/// may enable the other upstream backend, but this explicit selection remains deterministic.
15/// Custom providers and separate providers per signer/verifier are not supported.
16///
17/// # Errors
18/// Returns [`AuthError::CryptoProviderAlreadyInstalled`] if any caller has already initialized
19/// the upstream provider, including upstream automatic initialization. No provider is replaced
20/// or silently accepted. A duplicate call after Forge's successful initialization returns this
21/// error while existing JWT operations remain available. If another caller installed first,
22/// Forge stays unavailable; the product must treat that as a startup configuration failure.
23pub fn initialize_jwt_crypto_provider() -> Result<()> {
24 #[cfg(feature = "aws-lc-rs")]
25 let provider = &jsonwebtoken::crypto::aws_lc::DEFAULT_PROVIDER;
26 #[cfg(all(feature = "rust-crypto", not(feature = "aws-lc-rs")))]
27 let provider = &jsonwebtoken::crypto::rust_crypto::DEFAULT_PROVIDER;
28
29 #[cfg(any(feature = "aws-lc-rs", feature = "rust-crypto"))]
30 provider
31 .install_default()
32 .map_err(|_| AuthError::CryptoProviderAlreadyInstalled)?;
33
34 INITIALIZED.store(true, Ordering::Release);
35 Ok(())
36}
37
38pub(crate) fn ensure_initialized() -> Result<()> {
39 if INITIALIZED.load(Ordering::Acquire) {
40 Ok(())
41 } else {
42 Err(AuthError::CryptoProviderNotInitialized)
43 }
44}