Commit Graph

167 Commits

Author SHA1 Message Date
5c8448ff86 docs(architecture): fix OQ-05 — multi-connectivity endpoint, not multi-transport
Correct the conflation of quinn/TLS/iroh as interchangeable transports.
They are complementary connectivity modes serving different deployment
contexts: quinn (public IP + TLS), iroh (NAT traversal via relay), TCP
(handler-specific, not core). Clarify that TLS cert = network identity,
not auth identity. Map stealth mode to HTTP handler on standard ALPNs
instead of byte-peeking. Resolve OQ-05 as one-way door. SendStream/
RecvStream now use internal enum dispatch for both quinn and iroh
streams.
2026-06-16 12:41:03 +00:00
90d5f4eaf9 docs(architecture): spec alknet-core with per-crate subdocs, ADR-010/011
Add alknet-core architecture specs in docs/architecture/crates/core/ with
focused subdocuments for core types, endpoint, auth, and config. Write
ADR-010 (ALPN Router and Endpoint) defining AlknetEndpoint, HandlerRegistry,
accept loop, and graceful shutdown. Write ADR-011 (AuthContext Structure)
defining AuthContext fields, immutability in handle(), and IdentityProvider
injection pattern. Resolve OQ-04 (static registration), OQ-12 (file paths
only for v1). Add OQ-11 (auth observability). Fix remaining alknet-secret
references to alknet-vault across ADRs 003/004/005/009.
2026-06-16 12:07:17 +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
b47a6fe70b docs(architecture): resolve one-way doors, clean up Phase 0 specs
Resolve blocking one-way door decisions:
- ADR-007: BiStream is a trait, handlers receive Connection not BiStream
- ADR-008: Secret service is CLI-embedded, exposed via call protocol
- ADR-009: One-way door decision framework (classify by reversal cost)

Update existing documents:
- overview.md: add design principles, revise ProtocolHandler signature,
  update shared types, add WASM as design constraint
- open-questions.md: add door-type classifications, resolve OQ-01/OQ-08,
  move OQ-09/OQ-10 to deferred section, mark two-way doors as impl-deferred
- README.md: reflect resolved questions, remove crate spec stubs from index
- ADR-002: cross-reference ADR-007 for signature revision

Clean up premature artifacts:
- Remove 11 empty crate spec stubs (16-28 lines each, no unique content)
- Specs will be created when each crate enters Phase 1
2026-06-16 10:43:31 +00:00
f77b515968 docs(architecture): add Phase 0 architecture specs for ALPN-as-service model
Foundational architecture documents following the SDD process:

ADRs:
- 001: ALPN-based protocol dispatch (one endpoint, ALPN negotiation)
- 002: ProtocolHandler trait (replaces StreamInterface/MessageInterface)
- 003: Crate decomposition (one crate per handler, core provides shared infra)
- 004: Auth as shared core (IdentityProvider, hybrid resolution model)
- 005: irpc as call protocol foundation
- 006: ALPN string convention and connection model (alknet/ prefix, one ALPN per connection)

Docs:
- overview.md: crate graph, shared types, ALPN registry, failure modes
- README.md: index with doc table, ADR table, lifecycle definitions
- open-questions.md: 10 OQs across 7 themes (3 resolved, 7 open)

Crate spec stubs for all 11 planned crates (alknet-core through alknet CLI).

Key decisions resolved during self-review:
- AuthContext resolution is hybrid: endpoint resolves TLS-level auth,
  handlers resolve protocol-level auth (resolves OQ-02)
- ALPN is per-connection not per-stream, corrected ADR-001 (resolves OQ-06)
- ALPN naming uses alknet/ prefix without versions (resolves OQ-03)
- HandlerError return type on ProtocolHandler trait
- alknet/secret removed from ALPN registry until OQ-08 resolved
2026-06-15 22:14:58 +00:00
b5a4600d74 greenfield: clean slate for ALPN-as-service pivot
Delete old source crates (alknet-core, alknet, alknet-napi), old
architecture docs (ADRs, specs, open questions), old research docs
(phase2, event-sourcing, feasibility, etc.), old tasks, and obsolete
reference material (gitserver/MPL, honker, nats, rustfs, polyglot,
keystone, distributed-identity).

Keep: alknet-secret (standalone, compiles), pivot docs, iroh and ssh
references, rudolfs reference (MIT/Apache, fork candidate), ops docs,
sdd_process.md, and licenses.

Previous implementation preserved at /workspace/@alkdev/alknet-main/
for reference during porting.

Workspace compiles: cargo check + 14 tests pass for alknet-secret.
2026-06-15 12:08:08 +00:00
d003a4f4ec docs(research): revise cleanup plan to follow SDD process
Phase 5 now references the architect role and SDD process from
docs/sdd_process.md instead of creating ad-hoc spec stubs. Added
key new ADRs and architecture docs the architect will need to produce.
Updated gitserver reference note (MPL concern, archive it).
Kept rudolfs reference (MIT/Apache, fork candidate).

Also removed 'needs-update' status from the lifecycle states since
it's not part of the SDD process — stale docs get annotated with a
note and existing status, not a new status.
2026-06-15 09:17:07 +00:00
dc661dff82 docs(research): add pre-pivot cleanup plan
Plan to archive obsolete architecture docs, mark superseded ADRs,
remove replaced code modules (interface layer, stealth mode, control
channel), annotate stale-but-keeping docs, and create pivot spec stubs.

Key decisions:
- MPL gitserver reference archived (licensing risk + gix is the target)
- MIT/Apache rudolfs reference kept (fork candidate for git LFS)
- ADRs marked superseded, not deleted (historical record)
- Code deletion limited to modules the pivot explicitly replaces
2026-06-15 08:43:52 +00:00
ac3c36dfdc docs(research): add ALPN-as-service architecture pivot proposal 2026-06-14 14:07:00 +00:00
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