158 Commits

Author SHA1 Message Date
ff4f544fa5 docs(research): add nats-async and nats-server deep-dive references 2026-06-11 05:09:41 +00:00
f10dc23d13 docs(research): add russh-sftp deep-dive reference 2026-06-10 14:45:08 +00:00
f2a25f5bc1 docs(research): add russh and sftp-rs deep-dive references 2026-06-10 13:41:17 +00:00
5bb5e1064c docs(research): add iroh suite deep-dive references for iroh, irpc, iroh-blobs, iroh-gossip, iroh-live, and iroh-docs 2026-06-10 12:34:30 +00:00
6e71d1f306 docs(research): add polyglot SQL transpiler deep dive for multi-DB storage evaluation 2026-06-10 10:04:30 +00:00
bdb0b604e9 fix(secret): carry BIP39 passphrase in Unlock protocol variant
The Unlock variant had a single  field used as the
mnemonic, with no way to convey the BIP39 password extension (25th word).
The actor handler silently passed  for the passphrase, making it
impossible to unlock with a BIP39 passphrase via irpc.

Split into  +  to match
the spec and SecretServiceHandle::unlock() signature.
2026-06-10 09:26:17 +00:00
bda18f6bef docs(architecture): sync secret-service spec with implementation and add unlock-passphrase-gap task
Update secret-service.md to reflect the actual alknet-secret implementation:
- Fix dependency names/versions: secp256k1 (not libsecp256k1), version 0.29,
  add tokio/irpc-derive/hmac/rand, use workspace refs
- Add SecretServiceActor and CacheConfig to public API
- Add ethereum.rs module to crate structure, fix test_vectors.rs filename
- DerivedKey is move-only (not Clone), matching the stronger security impl
- Update BIP39 pseudocode to actual derive_path_from_seed() API
- Document derive_password_string() convenience method
- Document SecretServiceActor::spawn() in irpc integration model
- Update Unlock variant to target state: { mnemonic, passphrase: Option }
- Add implementation gap note pointing to unlock-passphrase-gap task

Add tasks/integration/phase3/secret-service/unlock-passphrase-gap.md:
- Fix Unlock protocol variant to carry both mnemonic and BIP39 passphrase
- Currently the irpc message only has passphrase: String (used as mnemonic)
- The handle supports both parameters but the protocol can't convey them
2026-06-10 09:18:59 +00:00
e827e7d61f chore: update task review-alknet-secret-spec-conformance status to completed 2026-06-10 07:44:13 +00:00
1942e2c2cb chore: update task irpc-secret-protocol-integration status to completed 2026-06-10 07:43:02 +00:00
470473fbb9 feat(secret): wire SecretProtocol to irpc with SecretServiceActor
Apply #[rpc_requests(message = SecretMessage)] to SecretProtocol enum with
#[rpc(tx=oneshot::Sender<Result<T, SecretServiceError>>)] and #[wrap] attributes
on each variant. Add SecretServiceActor that wraps SecretServiceHandle and
processes SecretMessage variants via mpsc channel. Update DerivedKey
serialization to use is_human_readable() so postcard preserves private_key
bytes while JSON redacts them. Add Serialize/Deserialize to SecretServiceError
for irpc wire format compatibility. Add tokio dependency for actor runtime.
2026-06-10 07:41:53 +00:00
47968ee48d chore: update task key-caching-ttl status to completed 2026-06-10 07:33:15 +00:00
d152818aa2 Merge key-caching-ttl with conflict resolution: integrated cache with secp256k1 and derive-password 2026-06-10 07:33:08 +00:00
2d5113cc1f chore: update task secp256k1-ethereum-derivation status to completed 2026-06-10 07:30:36 +00:00
9390c27f7d Merge secp256k1-ethereum-derivation with conflict resolution in service.rs tests 2026-06-10 07:30:30 +00:00
18b4083a69 feat(secret): add TTL-based key cache with LRU eviction
Implement KeyCache in cache.rs with CachedKey (Zeroize-protected),
CacheConfig (TTL + max_entries), and lazy eviction. Wire cache into
SecretServiceInner: derive_* methods check cache before re-deriving,
Lock clears and zeroizes all cache entries, encrypt/decrypt use
cached encryption key. Per ADR-038 and OQ-SVC-04.
2026-06-10 07:30:10 +00:00
fb77338ace chore: update task derive-password-implementation status to completed 2026-06-10 07:29:06 +00:00
f4cacdbcaf feat(secret): add BIP-0032 secp256k1 derivation for Ethereum keys behind feature flag
Fix derive_ethereum_key to use BIP-0032 instead of SLIP-0010, which
incorrectly handled unhardened indices in the Ethereum path m/44'/60'/0'/0/0.
2026-06-10 07:29:05 +00:00
c0010c144b Add derive_password and derive_password_string methods to SecretServiceHandle
Implements deterministic password derivation using SLIP-0010 at the
given path. derive_password returns raw truncated key bytes;
derive_password_string returns Base64url-encoded (no padding) string.
Both require unlocked state (ServiceLocked if locked). Includes unit
tests for determinism, different paths, length truncation, locked
error, and Base64url encoding.
2026-06-10 07:26:59 +00:00
7bf0538416 chore: update task crypto-test-vectors status to completed 2026-06-10 07:05:25 +00:00
91cffcd276 test(secret): add BIP39, SLIP-0010, AES-256-GCM, and cross-consistency test vectors 2026-06-10 07:05:18 +00:00
31936ef008 chore: update task derivedkey-zeroize-security status to completed 2026-06-10 06:17:15 +00:00
460a589888 Merge remote-tracking branch 'origin/feat/derivedkey-zeroize-security' 2026-06-10 06:16:55 +00:00
eae47c366b feat(alknet-secret): make DerivedKey zeroize-on-drop, non-Clone, with redacted serialization
Per ADR-038, DerivedKey.private_key now derives Zeroize with #[zeroize(drop)]
ensuring sensitive key material is zeroized before deallocation. DerivedKey
is now move-only (no Clone), and JSON/debug output redacts private_key as
"[REDACTED]". Deserialization still works for postcard/irpc wire format.

Also fixes clippy needless_borrows_for_generic_args in encryption.rs and
applies cargo fmt to existing code.
2026-06-10 06:16:38 +00:00
74a9dafb57 chore: update task encryption-salt-kdf status to completed 2026-06-10 06:11:30 +00:00
8eb687afc0 docs(alknet-secret): document EncryptedData.salt as reserved for future KDF-based key derivation
Add module-level documentation explaining that the salt field is reserved
for Phase B KDF-based key rotation. Add doc comment on the salt field
clarifying it is not used in v1 key derivation. Add TODO(Phase B) comment
on salt generation in encrypt().
2026-06-10 06:10:34 +00:00
c88e97d7d5 chore: update task spec-update-secret-service status to completed 2026-06-10 06:08:57 +00:00
916ed91b79 docs: close 7 spec gaps in secret-service.md
Address implementation-identified gaps:
- Add irpc integration model (SecretServiceHandle vs Client<SecretProtocol>, dispatch paths)
- Add Key Caching subsection (derivation path as cache key, 1-hour TTL, LRU, cleared on Lock)
- Specify DerivedKey.private_key must derive Zeroize per ADR-038
- Add Password Derivation subsection (HMAC-SHA512, Base64url encoding)
- Add secp256k1 derivation note (BIP-0032 algorithm, feature flag)
- Document EncryptedData.salt as reserved for future KDF-based key rotation
- Add Test Vectors section (BIP39, SLIP-0010, AES-256-GCM known-answer)
- Mark OQ-SVC-04 as resolved
- Update dependencies (secp256k1 feature-gated, future KDF deps)
- Update crate structure diagram (add cache.rs, vectors_tests.rs)
2026-06-10 06:08:15 +00:00
83ea66b5d1 chore: prep Phase 3 tasks and workspace for alknet-secret development
- Add irpc (0.16) and irpc-derive (0.16) as workspace dependencies
- Add irpc, irpc-derive, and secp256k1 (optional) to alknet-secret Cargo.toml
- Clarify encryption-salt-kdf task: Option B (document salt as reserved) is the
  chosen path per spec update, removing Option A acceptance criteria
- Update irpc-secret-protocol-integration task with concrete irpc crate details:
  real crate on crates.io v0.16, #[rpc_requests] macro, workspace config,
  AuthProtocol pattern reference, DerivedKey serialization considerations
- Fix secp256k1-ethereum-derivation task: correct crate name is secp256k1
  (not libsecp256k1), add version pin 0.29
2026-06-10 05:57:27 +00:00
9ec7627d80 chore: add Phase 3 secret-service decomposition tasks
9 atomic tasks for alknet-secret spec conformance and gap closure,
derived from architect's implementation review. Dependencies form
a 5-generation graph starting with spec update, then parallel
implementation tasks, ending with a review gate.

Tasks address: DerivedKey zeroize security, key caching with TTL,
irpc protocol integration, password derivation, secp256k1/Ethereum
derivation, encryption salt/KDF, crypto test vectors, and final
spec conformance review.
2026-06-10 04:14:39 +00:00
04e969982e feat(secret): add alknet-secret crate and architecture spec for Phase 3
Create the alknet-secret crate with BIP39 mnemonic generation, SLIP-0010
Ed25519 HD key derivation, AES-256-GCM encryption, and SecretProtocol
irpc service definition. This is Phase 3.1 from the integration plan.

Architecture changes:
- Promote secret-service.md to reviewed status with full spec format
  (crate structure, public API, security model, phase progression,
   ADR/OQ cross-references, wire format compatibility section)
- Add ADR-038 (seed lifecycle and memory security): zeroize for v1,
  mlock deferred to Phase B
- Add OQ-SEC-01 (mlock/VirtualLock for seed RAM) to open-questions.md
- Update README.md with ADR-038 and secret-service status

Crate structure:
- src/mnemonic.rs: BIP39 phrase generation, validation, seed derivation
- src/derivation.rs: SLIP-0010 HD key derivation, path constants (74')
- src/encryption.rs: AES-256-GCM encrypt/decrypt, EncryptedData type
- src/protocol.rs: SecretProtocol irpc enum, DerivedKey, KeyType
- src/service.rs: SecretServiceHandle with Unlock/Lock lifecycle
- 40 passing tests (unit + integration + doc)
2026-06-09 13:49:53 +00:00
d1c57627c6 chore: update task review-core-bridge-phase2 status to completed 2026-06-09 11:37:34 +00:00
bcbe2f1761 docs: sync architecture docs with Phase 2 implementation state 2026-06-09 11:37:14 +00:00
dc3c8208df chore: update task axum-http-router-scaffold status to completed 2026-06-09 11:28:55 +00:00
d5d4b3c153 feat(core): add axum HTTP router scaffold with auth middleware and stealth handoff
Add http feature flag with axum, hyper, hyper-util, tower, and http-body-util
dependencies. Create http module with auth middleware (extracts Bearer token,
calls IdentityProvider::resolve_from_token, attaches Identity to extensions)
and router scaffold (default 404 fallback, no operational routes yet). Replace
send_fake_nginx_404 with axum router handoff when http feature is enabled;
fake 404 behavior preserved when http is disabled. Wire HttpInterface with
build_router() method and pass IdentityProvider through Server to handle_connection.
2026-06-09 11:27:27 +00:00
309a586403 chore: update task api-keys-dynamic-config status to completed 2026-06-09 11:02:13 +00:00
8429758697 Merge remote-tracking branch 'origin/feat/api-keys-dynamic-config' 2026-06-09 11:01:48 +00:00
1f55844935 feat(core): add API keys to DynamicConfig.auth and extend IdentityProvider token resolution 2026-06-09 11:01:33 +00:00
bdb0af499a chore: update task ssh-session-call-protocol-bridge status to completed 2026-06-09 10:57:51 +00:00
1282b87e5d Merge remote-tracking branch 'origin/feat/ssh-session-call-protocol-bridge' 2026-06-09 10:56:57 +00:00
30f2910567 feat(core): bridge SshSession recv/send to call protocol via alknet-control:0 channel
Implement the SSH session to call protocol bridge:
- Add FrameFramedReader/FrameFramedWriter for async I/O of length-prefixed EventEnvelope frames
- SshSession::recv() reads InterfaceEvent frames from the alknet-control:0 channel via mpsc
- SshSession::send() writes EventEnvelope frames to the alknet-control:0 channel via mpsc
- Add ControlChannelBridge implementing ControlChannelHandler for routing channel data
- SshHandler::channel_open_direct_tcpip routes alknet-control:0 to the bridge task
- Session Identity attached to every InterfaceEvent produced by recv()
- ControlChannelRouter gains take_handler() for non-control alknet-* channel routing
2026-06-09 10:56:29 +00:00
bfc92d4827 chore: update task raw-framing-interface-implementation status to completed 2026-06-09 10:53:33 +00:00
33f85a8448 Merge remote-tracking branch 'origin/feat/raw-framing-interface-implementation' 2026-06-09 10:53:14 +00:00
752ead9d9f feat(core): implement RawFramingInterface accept/recv/send with first-frame auth
Implement RawFramingSession with tokio::io::split for read/write halves,
BufReader/BufWriter for buffered I/O, and decode_with_remainder for
partial frame reassembly. Add first-frame authentication via
IdentityProvider::resolve_from_token(). Add RawFramingConfig.auth
field for IdentityProvider reference. Update SshInterface test for
new RawFramingConfig shape.
2026-06-09 10:52:54 +00:00
0be0df5e96 chore: update task credential-provider-trait status to completed 2026-06-09 10:52:33 +00:00
ff4ab71ed7 Merge remote-tracking branch 'origin/feat/credential-provider-trait' 2026-06-09 10:52:11 +00:00
f8b4fb66b3 Add CredentialProvider trait, CredentialSet enum, and ConfigCredentialProvider
Define the outbound authentication abstraction in alknet_core::credentials:
- CredentialProvider trait with get_credentials and refresh_credentials
- CredentialSet enum with ApiKey, Basic, Bearer, S3AccessKey, OidcToken, Custom variants
- ConfigCredentialProvider reads credentials from DynamicConfig.credentials
- SecretStoreCredentialProvider stub returns None for all lookups (Phase 3)
- Wire CredentialProvider into OperationEnv via credentials() method
- Add credentials HashMap field to DynamicConfig
2026-06-09 10:51:54 +00:00
4d5fec3619 chore: update task listenconfig-http-dns-stubs status to completed 2026-06-09 10:51:19 +00:00
aa7e843e2f feat(core): add HttpListenerConfig/DnsListenerConfig builders, ListenerConfig validation with is_valid_pair, and Server::run Http/Dns stubs 2026-06-09 10:50:19 +00:00
752e61df4f chore: update task stream-interface-message-interface-split status to completed 2026-06-09 10:35:34 +00:00
9e807883de feat(core): rename Interface to StreamInterface, add MessageInterface, restructure ListenerConfig
Per ADR-035: split Interface trait into StreamInterface (stream-based, SSH/RawFraming)
and MessageInterface (request/response, HTTP/DNS). Remove TransportKind::Dns (DNS is
a MessageInterface). Change WebTransport { host } to { server_name: Option<String> }.
Restructure ListenerConfig from flat struct to enum with Stream/Http/Dns variants.
2026-06-09 10:26:04 +00:00