core_auth/
lib.rs

1//! Pluggable authentication backends for vault unlock.
2//!
3//! Provides a trait-based dispatch system for vault authentication methods.
4//! The `AuthDispatcher` tries non-interactive backends (SSH-agent, future TPM)
5//! first, falling back to password entry when no automatic method is available.
6//!
7//! The SSH-agent backend is currently a stub — actual agent communication is
8//! future work. The trait and types are defined to establish the contract.
9#![forbid(unsafe_code)]
10
11mod backend;
12mod dispatcher;
13mod password;
14pub mod password_wrap;
15mod ssh;
16mod ssh_types;
17pub mod vault_meta;
18
19pub use backend::{
20    AuthInteraction, FactorContribution, IpcUnlockStrategy, UnlockOutcome, VaultAuthBackend,
21};
22pub use dispatcher::AuthDispatcher;
23pub use password::PasswordBackend;
24pub use password_wrap::{PASSWORD_WRAP_VERSION, PasswordWrapBlob};
25pub use ssh::SshAgentBackend;
26pub use ssh_types::{ENROLLMENT_VERSION, EnrollmentBlob, SshKeyType};
27pub use vault_meta::{EnrolledFactor, VAULT_META_VERSION, VaultInitMode, VaultMetadata};
28
29/// Errors from authentication backends.
30///
31/// Does not implement `Clone` because the `Io` variant wraps `std::io::Error`
32/// which is not `Clone`. If clonability is needed for IPC forwarding, the
33/// error should be converted to a string representation first.
34#[derive(Debug, thiserror::Error)]
35pub enum AuthError {
36    #[error("backend not applicable: {0}")]
37    BackendNotApplicable(String),
38    #[error("enrollment not found for profile '{0}'")]
39    NotEnrolled(String),
40    #[error("SSH agent unavailable: {0}")]
41    AgentUnavailable(String),
42    #[error("unsupported key type: {0}")]
43    UnsupportedKeyType(String),
44    #[error("key unwrap failed (wrong key or tampered blob)")]
45    UnwrapFailed,
46    #[error("enrollment blob invalid: {0}")]
47    InvalidBlob(String),
48    #[error("no eligible SSH key found in agent")]
49    NoEligibleKey,
50    #[error("SSH agent protocol error: {0}")]
51    AgentProtocolError(String),
52    #[error("I/O error: {0}")]
53    Io(#[from] std::io::Error),
54}