From 91159bf574ddf1757cd0a0da212a6526c82ebecc Mon Sep 17 00:00:00 2001 From: "glm-5.2" Date: Tue, 23 Jun 2026 06:06:11 +0000 Subject: [PATCH] docs(architecture): remove derive_password and site_password_path from vault MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The password-manager pattern (deterministic per-site passwords from HD derivation) is not relevant to an RPC system's vault. Handlers call APIs (using API keys, OAuth tokens, mTLS), not websites with passwords. The vault is for cryptographic key derivation and credential encryption. Removes: - derive_password, derive_password_string from service.md - site_password_path from mnemonic-derivation.md - m/74'/1'/0'/{hash}' path from PATHS module and path semantics table - derive_password row from the cache table Resolves review #002 C9 (site_password_path hash mapping underspecified) by removing the feature rather than specifying the non-standard string→u32 mapping and Ed25519-as-password-entropy construction. If deterministic password generation is ever needed (browser-automation edge case), it can be re-added — the cost is near-zero. Removing it now eliminates permanent API surface inherited from a prior project's password-manager pattern. --- docs/architecture/crates/vault/README.md | 1 + .../crates/vault/mnemonic-derivation.md | 6 ++--- docs/architecture/crates/vault/service.md | 24 +------------------ .../019-vault-assembly-layer-only.md | 4 ++-- .../025-vault-local-only-dispatch.md | 18 ++++++++++++++ 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/docs/architecture/crates/vault/README.md b/docs/architecture/crates/vault/README.md index 11d4988..478226f 100644 --- a/docs/architecture/crates/vault/README.md +++ b/docs/architecture/crates/vault/README.md @@ -125,6 +125,7 @@ truth for drift tracking — if an item is fixed in source, update this table. | 4 | irpc dependency | `VaultProtocol` enum with `#[rpc_requests]`, `VaultServiceActor`, `Client`, irpc/postcard deps | Remove entirely — direct method calls on `VaultServiceHandle` (ADR-025) | `protocol.rs`, `service.rs`, `Cargo.toml` | [ADR-025](../../decisions/025-vault-local-only-dispatch.md) | | 5 | `DerivedKey` dual serialization | JSON redacts, postcard preserves bytes | Always redact on serialize; reject `"[REDACTED]"` on deserialize with error (ADR-025, resolves W8) | `protocol.rs` | [protocol.md → Serialization Redaction](protocol.md#serialization-redaction), [ADR-025](../../decisions/025-vault-local-only-dispatch.md) | | 6 | `HashMap::clear` zeroization | `KeyCache::clear()` removes entries and relies on `CachedKey`'s `Drop` impl for zeroization | Verify `HashMap::clear()` actually drops values (it does, but worth a test) | `cache.rs` | [service.md → Security Constraints](service.md#security-constraints) | +| 7 | `derive_password` / `site_password_path` | `derive_password`, `derive_password_string`, `site_password_path` methods exist | Remove entirely — password-manager pattern not relevant to RPC system's vault (ADR-025, resolves C9) | `service.rs`, `mnemonic-derivation.rs` | [ADR-025](../../decisions/025-vault-local-only-dispatch.md) | ## Public API diff --git a/docs/architecture/crates/vault/mnemonic-derivation.md b/docs/architecture/crates/vault/mnemonic-derivation.md index cef2179..327552d 100644 --- a/docs/architecture/crates/vault/mnemonic-derivation.md +++ b/docs/architecture/crates/vault/mnemonic-derivation.md @@ -199,9 +199,8 @@ pub mod PATHS { Helper functions construct parameterized paths: ```rust -pub fn device_path(index: u32) -> String; // m/74'/0'/0'/{index}' -pub fn site_password_path(site_hash: &str) -> String; // m/74'/1'/0'/{site_hash}' -pub fn encryption_path_for_version(version: u32) -> String; // m/74'/2'/0'/{version-2}' +pub fn device_path(index: u32) -> String; // m/74'/0'/0'/{index}' +pub fn encryption_path_for_version(version: u32) -> String; // m/74'/2'/0'/{version-2}' ``` ### Path semantics @@ -211,7 +210,6 @@ pub fn encryption_path_for_version(version: u32) -> String; // m/74'/2'/0'/{vers | `m/74'/0'/0'/0'` | Primary node identity (Ed25519) | Ed25519 | TLS raw key (ADR-010), node identity | | `m/74'/0'/0'/{n}'` | Worker/device identity | Ed25519 | Multi-device nodes, workers | | `m/74'/0'/1'/0'` | SSH host key | Ed25519 | SSH handler | -| `m/74'/1'/0'/{hash}'` | Site-specific deterministic password | Ed25519 bytes | Per-site passwords (not cached) | | `m/74'/2'/0'/0'` | Encryption key for external credentials | AES-256-GCM | Credential encryption (v2, see [encryption.md](encryption.md)) | | `m/44'/60'/0'/0/0` | Ethereum signing key | secp256k1 | Ethereum signing (feature-gated) | diff --git a/docs/architecture/crates/vault/service.md b/docs/architecture/crates/vault/service.md index a9f9e01..99ecb81 100644 --- a/docs/architecture/crates/vault/service.md +++ b/docs/architecture/crates/vault/service.md @@ -156,23 +156,6 @@ Derive a secp256k1 keypair at the given BIP-0032 path. Returns `UnsupportedKeyType` when the `secp256k1` feature is disabled. Returns a `DerivedKey` with `KeyType::Secp256k1` (33-byte compressed public key). -### derive_password(path, length) → Vec - -```rust -pub fn derive_password(&self, path: &str, length: usize) -> Result, VaultServiceError>; -pub fn derive_password_string(&self, path: &str, length: usize) -> Result; -``` - -Derive deterministic password bytes at the given path, truncated to -`length`. This is **not cached** — password derivation is cheap and -passwords are typically one-shot (derive, use, discard). The string -variant base64url-encodes the bytes (URL-safe, no padding). - -`derive_password` is the mechanism for per-site deterministic passwords: -the same seed + path always produces the same password. The path includes -a site hash (`site_password_path(site_hash)`) so different sites get -different passwords. - ## Encrypt and Decrypt ### encrypt(plaintext, key_version) → EncryptedData @@ -250,13 +233,8 @@ pub struct CacheConfig { | `derive_ed25519` | Yes | Derivation is expensive; keys are reused | | `derive_encryption_key` | Yes | Same — encryption key reused across calls | | `derive_ethereum_key` | Yes | Same | -| `derive_password` | No | Cheap derivation; passwords are one-shot | | `encrypt` / `decrypt` | Key cached | The encryption key (at `PATHS::ENCRYPTION`) is cached; the plaintext is not | -`derive_password` does not cache because it's a truncation of derived -bytes, not a keypair that's reused. Caching it would grow the cache with -unique paths (one per site hash) for no reuse benefit. - ## Dispatch The vault uses **direct method calls** on `VaultServiceHandle` — no actor, @@ -316,7 +294,7 @@ alknet-core error types at the assembly boundary (ADR-018). | RwLock for thread safety | — | Multiple readers (derive), exclusive writer (unlock/lock) | | TTL + LRU cache | — | Bounded memory, fresh keys, zeroized eviction | | Direct method calls (no actor) | [ADR-025](../../decisions/025-vault-local-only-dispatch.md) | No irpc, no message enum, no remote dispatch capability | -| `derive_password` not cached | — | One-shot; caching grows cache with no reuse | +| `derive_password` removed | [ADR-025](../../decisions/025-vault-local-only-dispatch.md) | Password-manager pattern not relevant to RPC system's vault; resolves C9 | ## Open Questions diff --git a/docs/architecture/decisions/019-vault-assembly-layer-only.md b/docs/architecture/decisions/019-vault-assembly-layer-only.md index 4a50d43..14a7a33 100644 --- a/docs/architecture/decisions/019-vault-assembly-layer-only.md +++ b/docs/architecture/decisions/019-vault-assembly-layer-only.md @@ -20,8 +20,8 @@ perspective?** The vault provides a `VaultServiceHandle` with `unlock`, `lock`, `derive_ed25519`, `derive_encryption_key`, `derive_ethereum_key`, -`derive_password`, `encrypt`, and `decrypt` methods. Who is allowed to call -these, and through what path? +`encrypt`, and `decrypt` methods. Who is allowed to call these, and +through what path? The candidates: diff --git a/docs/architecture/decisions/025-vault-local-only-dispatch.md b/docs/architecture/decisions/025-vault-local-only-dispatch.md index 5433519..1bb722c 100644 --- a/docs/architecture/decisions/025-vault-local-only-dispatch.md +++ b/docs/architecture/decisions/025-vault-local-only-dispatch.md @@ -203,6 +203,19 @@ version of ADR-018's intent. exclusive writes (unlock/lock). The actor's sequential processing was actually *worse* for throughput than the RwLock. Removing the actor makes the concurrency model visible and correct. +- `derive_password` and `site_password_path` are removed from the vault's + API and path model. The password-manager pattern (deterministic per-site + passwords from HD derivation) is not relevant to an RPC system's vault — + handlers call APIs (using API keys, OAuth tokens, mTLS), not websites + with passwords. The vault is for cryptographic key derivation and + credential encryption. This resolves review #002 C9 (site_password_path + hash mapping underspecified) by removing the feature rather than + specifying the non-standard string→u32 mapping and Ed25519-as-password- + entropy construction. If deterministic password generation is ever needed + (browser-automation edge case), it can be re-added or implemented as a + separate concern — the cost is near-zero, and removing it now eliminates + permanent API surface that was inherited from a prior project's + password-manager pattern. **Negative:** @@ -247,6 +260,11 @@ version of ADR-018's intent. in protocol.md goes away. If a future vault-server crate exposes some operations remotely, *that crate* defines the access policy in its own ADR. +- **C9 (site_password_path hash mapping underspecified)**: resolved. The + `derive_password` / `derive_password_string` / `site_password_path` + methods are removed from the vault's API. The password-manager pattern + is not relevant to an RPC system's vault. No hash mapping to specify, + no Ed25519-as-password-entropy question to answer. ## Assumptions