Skip to main content

basil_core/
lib.rs

1//! `basil-core` library: broker core, service adapters, and transport wiring.
2//!
3//! - [`core::catalog`] is the key inventory + authorization policy loaded at
4//!   startup.
5//! - [`core::state`] bundles the loaded policy + backend manager shared across
6//!   tonic services.
7//! - [`service`] contains tonic service adapters.
8//! - [`transport`] owns tonic wiring, peer extraction, and authorization helpers.
9
10// Index/slice in test code is fine (fixed test fixtures); the no-panic
11// `indexing_slicing` gate has no test-allow config option, unlike unwrap/expect.
12#![cfg_attr(test, allow(clippy::indexing_slicing))]
13
14#[cfg(all(
15    feature = "keystore-backend",
16    not(any(feature = "db-keystore", feature = "onepassword"))
17))]
18compile_error!("feature `keystore-backend` requires feature `db-keystore`, `onepassword`, or both");
19
20/// Default Unix socket path used by the daemon and local client tooling.
21pub const DEFAULT_SOCKET_PATH: &str = "/tmp/basil-agent.sock";
22
23/// Ensure a process-wide default rustls [`CryptoProvider`](rustls::crypto::CryptoProvider)
24/// is installed before any `reqwest` client is built.
25///
26/// `reqwest` is compiled with the `rustls-no-provider` feature (its `rustls`
27/// feature would pull in the `aws-lc-rs` C toolchain, which is forbidden here),
28/// so building a client panics unless a default provider is already installed.
29/// This daemon must never panic, so we install the pure-Rust `ring` provider
30/// (the same one used for the JWKS server and gRPC transport) exactly once. A
31/// prior install by an embedder is fine and left untouched (the returned `Err`
32/// only signals that a provider was already set).
33pub(crate) fn ensure_crypto_provider() {
34    use std::sync::Once;
35    static INSTALL: Once = Once::new();
36    INSTALL.call_once(|| {
37        let _ = rustls::crypto::ring::default_provider().install_default();
38    });
39}
40
41pub mod agent_cli;
42pub mod bundle_cli;
43pub mod core;
44pub mod doctor;
45pub mod init;
46pub mod service;
47pub mod transport;
48pub mod unlock;
49
50#[cfg(feature = "tpm2")]
51pub use core::identity;
52pub use core::ml_dsa_sign;
53pub use core::{
54    actor, audit, backend, capability, catalog, decision, ed25519_sign, event, manager, minter,
55    ml_kem_envelope, peer, reconcile, reload, revocation, seal, state, x25519_seal,
56};
57pub use service::broker as grpc;
58#[cfg(feature = "http")]
59pub use service::jwks;
60pub use service::sds;
61pub use service::spiffe;
62pub use transport::grpc_server;
63
64pub use audit::{AuditLog, ReloadActor};
65#[cfg(feature = "keystore-backend")]
66pub use backend::keystore::KeystoreBackend;
67pub use backend::spiffe::{SpiffeConfig, SpiffeVaultBackend};
68pub use backend::vault::VaultBackend;
69pub use backend::{Backend, BackendError, NewKey};
70pub use capability::{
71    CapabilityError, CapabilityGap, CapabilityPolicy, CapabilitySummary, enforce_capabilities,
72};
73pub use catalog::{
74    BackendKind, Capability, Catalog, Config, LoadError, LoadWarning, MissingPolicy,
75    ResolvedPolicy, load,
76};
77pub use decision::{DecisionRecord, Outcome};
78pub use event::{BrokerEvent, BrokerEventKind, EventSource};
79pub use grpc_server::{DEFAULT_SOCKET_MODE, ServerConfig, run as run_grpc};
80pub use manager::{BackendManager, ManagerError};
81pub use peer::PeerInfo;
82pub use reconcile::{CheckReport, KeyCheck, KeyStatus, ReconcileError, ReconcileSummary};
83pub use reload::{ReloadError, ReloadInputs, ReloadOutcome, check_reload, reload_generation};
84pub use revocation::JwtRevocationStore;
85pub use seal::{
86    BackendCred, CredBundle, MasterKek, MethodKind, MethodRegistry, ParsedBundle, SealError,
87    SlotSpec, UnlockError, UnlockMethod,
88};
89pub use state::{
90    BrokerLimits, BrokerState, DEFAULT_MAX_ENCRYPT_SIZE, DEFAULT_MAX_PAYLOAD_SIZE,
91    DEFAULT_ROTATION_GRACE_VERSIONS, DEFAULT_SVID_TTL_SECS, Generation, INITIAL_GENERATION_ID,
92};