Commit Graph

9 Commits

Author SHA1 Message Date
9eab93100e vault: version-indexed encryption key paths, bump CURRENT_KEY_VERSION to 2, add rotate (task: vault/key-versioning-rotation)
Drift items #3, #9, #10: implement the version-indexed key rotation mechanism
(ADR-021). Bump CURRENT_KEY_VERSION to 2 (HD-derived per ADR-020). Add
encryption_path_for_version in derivation.rs, derive_encryption_key_for_version
+ version-aware encrypt/decrypt + rotate method on VaultServiceHandle. Each
version maps to a distinct derivation path; the blob carries its own version.

Refs: docs/architecture/crates/vault/README.md drift #3, #9, #10
Implements: ADR-020, ADR-021

# Conflicts:
#	crates/alknet-vault/src/derivation.rs
#	crates/alknet-vault/src/service.rs
2026-06-23 13:39:05 +00:00
bc8e329f90 vault: replace unwrap() on RwLock with poisoned-lock recovery (task: vault/poisoned-lock-recovery)
Drift item #2: replace all .read().unwrap()/.write().unwrap() calls in
VaultServiceHandle with .unwrap_or_else(|e| e.into_inner()) to recover from
poisoned locks instead of bricking the vault. Added test_poisoned_lock_recovery
that poisons the lock via a panicking thread and verifies the vault remains
usable.

Refs: docs/architecture/crates/vault/README.md drift #2
Implements: ADR-025

# Conflicts:
#	crates/alknet-vault/src/service.rs
2026-06-23 13:35:53 +00:00
55d356cb4e feat(vault): version-indexed encryption key paths, CURRENT_KEY_VERSION=2, rotate method (ADR-021)
- Bump CURRENT_KEY_VERSION from 1 to 2 (v1 reserved for TS PBKDF2 legacy per ADR-020)
- Add derivation::encryption_path_for_version(version) -> m/74'/2'/0'/{version-2}', returns InvalidPath for version < 2
- Add VaultServiceHandle::derive_encryption_key_for_version(version), cached by path, returns InvalidPath for version < 2
- encrypt/decrypt now derive at encryption_path_for_version(key_version) instead of fixed PATHS::ENCRYPTION
- Add VaultServiceHandle::rotate(encrypted, to_version): decrypt old, re-encrypt new
- Update existing tests to use v2; add round-trip, rotation, partial-rotation, and invalid-version tests

Task: vault/key-versioning-rotation
2026-06-23 13:35:44 +00:00
ad1174b485 vault: change unlock_new return type to Zeroizing<String> (task: vault/unlock-new-zeroizing-return)
Drift item #8: the mnemonic phrase is the root of trust — it must not linger in
freed heap memory. Changed unlock_new return from String to Zeroizing<String>
(zeroized on drop). Existing tests work via Deref coercion.

Refs: docs/architecture/crates/vault/README.md drift #8
Implements: ADR-025 (resolves W7)
2026-06-23 13:33:55 +00:00
9045dd83d3 vault: replace RwLock unwrap with poisoned-lock recovery
Replace all .read().unwrap() and .write().unwrap() calls in
VaultServiceHandle methods with .unwrap_or_else(|e| e.into_inner())
so a panic while holding the lock does not brick the vault for all
subsequent operations. Add unit test that poisons the lock and
verifies the next call recovers.
2026-06-23 13:33:00 +00:00
685413dee4 vault: return Zeroizing<String> from unlock_new
Change unlock_new return type from String to Zeroizing<String>
so the generated mnemonic phrase is zeroized on drop and does not
linger in freed heap memory. Resolves drift item #8 / review W7.
2026-06-23 13:33:00 +00:00
06b715322a refactor(vault): remove derive_password and site_password_path (ADR-025)
Drop the password-manager pattern from alknet-vault (drift item #7,
ADR-025, resolves review #002 C9). Site-specific password derivation
is not relevant to an RPC system's vault.

Removed:
- derive_password method from VaultServiceHandle (service.rs)
- derive_password_string method from VaultServiceHandle (service.rs)
- site_password_path function from derivation.rs
- site-password derivation path row from derivation.rs doc table
- All password-derivation tests from service.rs and derivation.rs
- Now-unused base64 URL_SAFE_NO_PAD import from service.rs
2026-06-23 13:32:45 +00:00
9028fca302 refactor(vault): remove irpc actor dispatch — direct method calls on VaultServiceHandle (ADR-025)
Drop the irpc-based actor dispatch path from alknet-vault and convert to
direct method calls on VaultServiceHandle (drift item #4, ADR-025).

Removed:
- VaultProtocol enum with #[rpc_requests] derive from protocol.rs
- VaultServiceActor (mpsc + oneshot dispatch loop) from service.rs
- VaultService wrapper struct (only the handle is needed)
- Client<VaultProtocol> usage
- irpc, irpc-derive, tokio from [dependencies]
- postcard from [dev-dependencies]
- VaultMessage/VaultProtocol/VaultServiceActor re-exports from lib.rs
- Serialize/Deserialize derives from VaultServiceError
- postcard round-trip tests from protocol.rs
- actor tokio::test tests from service.rs

The vault now has zero async runtime dependency and zero RPC framework
dependency — it is local-only by construction. VaultServiceHandle is the
sole API: Arc<std::sync::RwLock<VaultServiceInner>> with synchronous
methods. lib.rs re-exports match the vault README Public API section.

Also fixes pre-existing clippy field_reassign_with_default warnings in
cache.rs tests so cargo clippy -- -D warnings passes.
2026-06-23 13:20:28 +00:00
80128a56e5 refactor: rename alknet-secret to alknet-vault
Rename the crate from alknet-secret to alknet-vault to better reflect its
purpose as a local key vault (seed management, key derivation, encryption)
rather than a network service.

Symbol renames:
- SecretService → VaultService
- SecretServiceHandle → VaultServiceHandle
- SecretServiceActor → VaultServiceActor
- SecretServiceError → VaultServiceError
- SecretProtocol → VaultProtocol
- SecretMessage → VaultMessage
- ServiceLocked → VaultLocked
- alknet_secret → alknet_vault (crate name)

Update ADR-008 with vault access pattern: the vault is a capability source,
not a service endpoint. The CLI injects derived/decrypted material into
operation contexts — handlers never hold vault references.
2026-06-16 11:10:07 +00:00