Rename the crate from alknet-vault to alkvault across source and docs: - Cargo.toml: package name and lib name (alknet_vault -> alkvault) - src/ doc comments and doc-test use statements - tests/ use statements and one string literal Convert references to non-vault alknet ADRs (003, 005, 008, 010, 014, 064) that were broken local links into @alkdev/alknet: cross-repo references, matching the alktype sibling pattern. Local ADR/OQ references are now proper links. Rewrote monorepo path references (crates/alknet-vault/src/...) to the flat layout (src/...). Fixed sdd_process.md package name (@alkdev/storage -> @alkdev/alkvault). ADR/OQ renumbering is deferred to a subsequent pass per the alknet- origin numbering convention. Generic prose 'vault' and type names (VaultServiceHandle, VaultServiceError, etc.) are unchanged. Build, 108 tests, and clippy all pass clean.
8.4 KiB
status, last_updated
| status | last_updated |
|---|---|
| stable | 2026-06-23 |
alkvault
Local key vault: BIP39 mnemonic generation, SLIP-0010 Ed25519 HD key derivation, BIP-0032 secp256k1 derivation (feature-gated), and AES-256-GCM encryption. Holds the master seed — the root of trust for all derived keys and encrypted credentials in the alknet system.
What This Crate Is
alkvault is a standalone crate with zero alknet crate dependencies
(ADR-018) and zero RPC framework dependencies (ADR-025). It provides the
cryptographic primitives and runtime API for managing the root of trust.
The CLI binary (the alknet crate) is the sole component that talks to the
vault directly (ADR-019) — handlers receive derived/decrypted material
through capabilities, never through a vault reference.
The vault is not a network service. It has no ALPN, no
ProtocolHandler implementation, no operations registered in the call
protocol (ADR-008, ADR-014), and no remote dispatch capability (ADR-025).
The vault is local-only by construction — direct method calls on
VaultServiceHandle, no actor, no message enum, no wire format. The master
seed and derived private keys never cross the network.
Documents
| Document | Status | Description |
|---|---|---|
| mnemonic-derivation.md | stable | BIP39, SLIP-0010, BIP-0032, derivation paths, key types |
| encryption.md | stable | AES-256-GCM, EncryptedData, key versioning, HD derivation (ADR-020) |
| service.md | stable | VaultServiceHandle lifecycle, direct dispatch, cache, error model |
| protocol.md | stable | DerivedKey redaction, KeyType, serialization behavior |
Applicable ADRs
| ADR | Title | Relevance |
|---|---|---|
| 018 | Vault as Standalone Crate | Zero alknet crate dependencies |
| 019 | Vault Assembly-Layer-Only Access | The assembly layer is the sole caller |
| 020 | HD Derivation for Encryption Keys | SLIP-0010 derivation, not PBKDF2; salt unused in v2 |
| 021 | Key Rotation via Version-Indexed Paths | Version-indexed paths; rotate re-encrypts |
| 025 | Vault Local-Only Dispatch | Dropped irpc; direct method calls; local-only by construction |
| 026 | Vault Key Model — HD Derivation | HD derivation from BIP39 seed; 74' coin type; AES-256-GCM |
Related ADRs in the parent @alkdev/alknet repo
These ADRs are not copied here (they are not vault-specific), but the
vault's design depends on them. They live in the parent @alkdev/alknet
workspace.
| ADR | Title | Relevance |
|---|---|---|
@alkdev/alknet: docs/architecture/decisions/003-crate-decomposition.md |
Crate Decomposition | alkvault's standalone position |
@alkdev/alknet: docs/architecture/decisions/008-secret-service-integration.md |
Vault Integration Point | CLI-embedded, capability source |
@alkdev/alknet: docs/architecture/decisions/010-alpn-router-and-endpoint.md |
ALPN Router and Endpoint | Ed25519 as default curve for TLS raw key identity |
@alkdev/alknet: docs/architecture/decisions/014-secret-material-flow-and-capability-injection.md |
Secret Material Flow and Capability Injection | Capabilities carry vault-derived material |
Relevant Open Questions
| OQ | Title | Status | Relevance |
|---|---|---|---|
| OQ-20 | Encryption key derivation | resolved (ADR-020) | HD derivation from seed; salt field unused in v2 |
| OQ-21 | Remote vault access | resolved (ADR-025) | Vault is local-only by construction; remote access requires a separate vault-server crate with its own ADR |
| OQ-22 | Key rotation mechanism | resolved (ADR-021) | Version-indexed paths; rotate method |
Key Design Principles
- Standalone: The vault depends on no alknet crate and no RPC framework. It defines its own types and errors. External crates depend on the vault; the vault depends on nothing in alknet.
- Assembly-layer only: The vault's API is consumed by the CLI binary, not by handlers. Handlers receive material through capabilities (ADR-014). The vault is not on the wire.
- Local-only by construction: The vault has no remote dispatch
capability. Direct method calls on
VaultServiceHandle— no actor, no message enum, no wire format (ADR-025). Remote access, if ever needed, requires a separate crate with its own ADR. - Zeroize everything sensitive: The mnemonic, seed, derived private
keys, encryption keys, and cached keys all implement
ZeroizeandZeroizeOnDrop. Secret material does not linger in freed heap memory. - Deterministic derivation: The same mnemonic + passphrase + path always produces the same key. Derivation is reproducible across runs and across nodes.
- OsRng for nonces: AES-GCM IVs and any cryptographic nonces use
OsRng(or equivalent CSPRNG), neverrand::random(). IV reuse under the same key is catastrophic for GCM. - No
unwrap()orexpect()outside tests: vault operations propagate errors. A poisoned lock is recovered withunwrap_or_else(|e| e.into_inner()), notunwrap(). A panic in one vault operation must not brick the vault for all other operations.
Security Constraints
These are security-critical implementation requirements, not architectural decisions (the architecture is locked by the ADRs above). They are documented here so implementation agents don't miss them. See service.md → Security Constraints for the full list.
- OsRng for IVs: AES-GCM IVs must use
OsRng, notrand::random(). - Zeroized drop:
Seed,Mnemonic,ExtendedPrivKey,Secp256k1ExtendedPrivKey,EncryptionKey,CachedKey, andDerivedKeyall deriveZeroizeandZeroizeOnDrop. The cache must clear on drop, not just on explicitlock(). - No
unwrap()outside tests: poisoned lock recovery usesunwrap_or_else(|e| e.into_inner())or explicit error propagation. - DerivedKey redaction in serialization:
DerivedKeyserializes theprivate_keyas"[REDACTED]"in all formats (ADR-025 dropped the postcard/remote path that previously preserved bytes in binary formats). Deserialization rejects"[REDACTED]"with an error (resolves review #002 W8). The redaction is a defense-in-depth measure for logging safety, not the primary control — the primary control is thatDerivedKeynever crosses the call protocol wire (ADR-014).
Public API
The vault re-exports its primary types from the crate root:
// Mnemonic and seed
pub use mnemonic::{Language, Mnemonic, Seed};
// Derivation
pub use derivation::{DerivationError, ExtendedPrivKey, PATHS};
// Derivation helpers (derive_path_from_seed, parse_derivation_path,
// device_path, encryption_path_for_version) are accessible as
// alkvault::derivation::* — not re-exported at crate root to avoid
// clutter, but fully public.
// Encryption
pub use encryption::{EncryptedData, EncryptionError, EncryptionKey};
pub use encryption::CURRENT_KEY_VERSION;
// Key types (DerivedKey, KeyType)
pub use protocol::{DerivedKey, KeyType};
// Service (runtime)
pub use service::{VaultServiceError, VaultServiceHandle};
// Cache
pub use cache::CacheConfig;
The secp256k1 feature flag gates Ethereum (BIP-0032) derivation:
#[cfg(feature = "secp256k1")]
pub mod ethereum;
References
@alkdev/alknet: docs/architecture/decisions/003-crate-decomposition.md— crate decomposition (alkvault's standalone position)@alkdev/alknet: docs/architecture/decisions/008-secret-service-integration.md— vault integration point (CLI-embedded, capability source)@alkdev/alknet: docs/architecture/decisions/010-alpn-router-and-endpoint.md— ALPN router and endpoint (Ed25519 as default curve for TLS raw key identity)@alkdev/alknet: docs/architecture/decisions/014-secret-material-flow-and-capability-injection.md— secret material flow and capability injection (capabilities carry vault-derived material)
Note
: Cross-repo references (
@alkdev/alknet: ...) point to the parent@alkdev/alknetworkspace where this crate originated. The artifacts are preserved there as historical context; they are not part of this standalone repo.