Files
alknet/tasks/integration/phase3/secret-service/spec-update-secret-service.md

7.3 KiB

id, name, status, depends_on, scope, risk, impact, level
id name status depends_on scope risk impact level
spec-update-secret-service Update secret-service.md spec to close implementation-identified gaps completed
narrow low phase implementation

Description

Update docs/architecture/secret-service.md to address seven gaps identified during the architect's initial implementation of alknet-secret. The tests pass and the code isn't "wrong," but the spec needs to be brought into alignment with what was learned and with what the implementation needs to be complete.

This is a spec-first task — no code changes here, just documentation. The spec must be complete enough that the subsequent implementation tasks can be picked up without ambiguity.

Gaps to Close

  1. irpc integration undefined (biggest gap): The spec says SecretProtocol uses #[rpc_requests(message = SecretMessage)] but doesn't define the concrete wiring. How does a local SecretServiceHandle relate to the irpc protocol? What's the Client<SecretProtocol> type? Where does the service run (in-process mpsc vs remote QUIC)? The current code has pub type SecretMessage = SecretProtocol; as a placeholder.

  2. Key caching strategy: The security model table says "derived keys cached in RAM" but never specifies: what's the cache key? What's the TTL? Is it LRU? OQ-SVC-04 was resolved "yes, with TTL default 1 hour" but the spec doesn't reflect this resolution. Current implementation has no caching at all.

  3. DerivedKey security properties: The struct carries private_key: Vec<u8> but doesn't derive Zeroize. ADR-038 says all sensitive material must zeroize. The spec should specify this.

  4. DerivePassword specification: The SecretProtocol::DerivePassword variant exists but has no specification for how deterministic password derivation works: what hash function? What encoding? What character set?

  5. secp256k1/Ethereum derivation: DeriveEthereumKey is in the protocol but the spec doesn't acknowledge that BIP-0032 secp256k1 (path m/44'/60'/0'/0/0) requires a fundamentally different derivation algorithm and crate than SLIP-0010 Ed25519.

  6. Test vectors requirement: A crypto crate needs known-answer tests against published BIP39/SLIP-0010 test vectors. The spec doesn't reference any.

  7. EncryptedData.salt purpose: The salt field is generated and stored but not used in key derivation. The spec should either specify that the salt is used in a KDF (PBKDF2/HKDF) to derive the AES key, or document it as reserved for future KDF-based key rotation.

Changes to Make

In docs/architecture/secret-service.md:

  • Section: SecretProtocol irpc Service — Replace the SecretProtocol enum definition with one that includes the irpc integration model: define SecretServiceHandle (local, in-process) vs SecretProtocol irpc client (remote), clarify the two dispatch paths, and specify that SecretMessage is the irpc wire type (generated by #[rpc_requests]).

  • Section: Security Model — Add a "Key Caching" subsection specifying: derivation path as cache key, TTL of 1 hour (configurable), LRU eviction, cache cleared on Lock. Per OQ-SVC-04 resolution.

  • Section: Key Derivation — Add a note after the DerivedKey struct that private_key must derive Zeroize per ADR-038. This means DerivedKey cannot use #[derive(Clone)] directly on the private key field; it needs a custom implementation that zeroizes the source on clone.

  • Section: Key Derivation (after derivation paths table) — Add a "Password Derivation" subsection specifying: DerivePassword uses HMAC-SHA512 at the derivation path, truncates to length bytes, and encodes as Base64url (no special character set in v1). The path format is m/74'/1'/0'/{hash}' where {hash}' is a site-specific hardened index.

  • Section: Key Derivation (after Ethereum path) — Add a "secp256k1 Derivation" note: DeriveEthereumKey uses BIP-0032 (not SLIP-0010) at path m/44'/60'/0'/0/0, requiring the libsecp256k1 crate. This is a different derivation algorithm from Ed25519. The alknet-secret crate should gate this behind a secp256k1 feature flag.

  • Section: AES-256-GCM Encryption — Specify that EncryptedData.salt is currently reserved for future KDF-based key rotation. In v1, the encryption key is derived directly from the seed at path m/74'/2'/0'/0' without a salt-based KDF. The salt field is included for forward compatibility: when key rotation is implemented, the salt will be used as input to HKDF or PBKDF2 for stretch-based key derivation. For now, the salt is random and stored but not used in key derivation.

  • New Section: Test Vectors — Require known-answer tests against:

    • BIP39 test vectors (mnemonic → seed)
    • SLIP-0010 test vectors (seed → master key, master key → child key at m/74'/0'/0'/0')
    • IEEE P802.1ASck test vectors for AES-256-GCM (or equivalent published vectors)
  • Section: Open Questions — Mark OQ-SVC-04 as resolved (key caching: yes, TTL default 1 hour, LRU eviction). Add note about OQ-SVC-03 (EncryptedData compatibility: wire format stable, migration path is re-encrypt with new key version).

  • Dependencies section — Add libsecp256k1 (behind secp256k1 feature flag) and hkdf/pbkdf2 (deferred, for Phase B KDF — listed as future dependency, not current). Update irpc line to clarify it's required but the integration model needs specification.

  • Crate Structure — Update to include cache.rs module for key caching.

Acceptance Criteria

  • secret-service.md has a new subsection on irpc integration (local SecretServiceHandle vs remote SecretProtocol client, dispatch paths)
  • secret-service.md has a "Key Caching" subsection specifying derivation path as cache key, 1-hour TTL, LRU eviction, cleared on Lock
  • secret-service.md notes that DerivedKey.private_key must derive Zeroize per ADR-038
  • secret-service.md has a "Password Derivation" subsection specifying HMAC-SHA512 → Base64url encoding
  • secret-service.md has a "secp256k1 Derivation" note specifying BIP-0032 algorithm and secp256k1 feature flag
  • secret-service.md specifies that EncryptedData.salt is reserved for future KDF-based key rotation, not used in v1 key derivation
  • secret-service.md has a "Test Vectors" section requiring BIP39, SLIP-0010, and AES-256-GCM known-answer tests
  • OQ-SVC-04 is marked as resolved in secret-service.md
  • Dependencies section updated with secp256k1 (feature-gated) and noted future KDF deps
  • Crate structure diagram updated to include cache.rs

References

  • docs/architecture/secret-service.md — The spec being updated
  • docs/architecture/decisions/038-seed-lifecycle-memory-security.md — ADR-038 (zeroize requirement)
  • docs/architecture/decisions/027-crate-decomposition.md — ADR-027 (crate independence)
  • docs/research/services.md — SecretProtocol definition source
  • crates/alknet-secret/ — Current implementation (reference for what exists)

Notes

This is a spec-only task. No code changes. The goal is to make the spec complete enough that subsequent implementation tasks have zero ambiguity about what to build.

The architect's message (msg_eacbd63b2001DsTCHZn04meEpB) identified exactly these 7 gaps. This task closes them in the spec so that the implementation tasks can be done against a single source of truth.

Summary

To be filled on completion