Commit Graph
99 Commits
Author SHA1 Message Date
glm-5.1 a107aebeb7 Add Phase 2 research: credential provider, interface model, and TLS transport architecture
Three research documents for Phase 2 planning:

- credential-provider.md: Outbound auth (CredentialProvider trait, CredentialSet enum),
  account model as storage-layer concern (Identity.id as account UUID), SecretStoreCredentialProvider,
  ManagedCredentialProvider, self-hosted service auth analysis (rustfs S3/OIDC, gitea OAuth2),
  implementation phases A-D.

- interface-model.md: StreamInterface vs MessageInterface trait design, HTTP interface
  as axum handler, DNS as MessageInterface, unified auth across all interfaces
  (AuthToken + API keys via resolve_from_token), removal of TransportKind::Dns.

- tls-transport.md: Unified multi-interface architecture on port 443. Byte-peek protocol
  detection (existing stealth mode) routes SSH vs axum. Axum multiplexes REST, WebSocket,
  SSE, gRPC. QUIC/UDP with ALPN routing for WebTransport and iroh P2P. Single AuthToken
  mechanism for all non-SSH interfaces. Four primitive operations (call/batch/schema/subscribe)
  map to HTTP, MCP, and DNS.
2026-06-08 10:37:20 +00:00
glm-5.1 5cac68f95c docs(interface): document SshSession recv/send stubs as planned future work
Add doc comments and TODO markers to SshSession::recv() and send()
explicitly marking them as Phase 1 stubs. Notes that call protocol
event bridging from SSH channels is planned for Phase 2/3.
2026-06-08 05:35:43 +00:00
glm-5.1 64c54b965e docs: add ADR number references to module doc comments
New Phase 1 modules should follow the existing pattern of referencing
ADR numbers in module-level doc comments for discoverability, matching
the style in transport/mod.rs.
2026-06-08 05:35:08 +00:00
glm-5.1 619a6dcc77 feat(api): add #[non_exhaustive] to public types likely to evolve
ForwardingAction, TargetPattern, ForwardingRule, OperationType,
InterfaceConfig, InterfaceKind, DynamicConfig, and CallError are all
likely to gain variants/fields in future phases. Marking them
#[non_exhaustive] now prevents downstream breakage when new
variants/fields are added. Added constructor methods for types that
are constructed from other crates.
2026-06-08 05:34:15 +00:00
glm-5.1 b0a885ea40 fix(config): replace panics in parse_proxy_config with proper Result errors
parse_proxy_config was using expect()/unwrap()/panic!() which would
crash the process on malformed proxy config strings instead of
returning a descriptive error. Now returns ConfigError::ProxyConfigInvalid
with the specific issue (bad scheme, bad address). Added tests for
invalid scheme, invalid address, and end-to-end from_serve_options.
2026-06-08 05:30:23 +00:00
glm-5.1 68728451a4 fix(napi): wire NapiServerHandler through IdentityProvider and ForwardingPolicy
NapiServerHandler was bypassing IdentityProvider, calling
config.auth.authenticate_publickey() directly, which meant no Identity
was stored on the session and per-identity forwarding rules could not
match. It also skipped ForwardingPolicy::check() entirely, defeating
forwarding access control for NAPI-served tunnels. Both are now
consistent with ServerHandler and SshHandler behavior.
2026-06-08 05:28:02 +00:00
glm-5.1 eed3396705 tasks: add 5 cleanup tasks from Phase 1 review, mark review complete
Review found Phase 1 approved with minor issues. Created cleanup tasks:
- napi-identity-provider-wiring (bug: NAPI bypasses IdentityProvider)
- panic-free-static-config (code smell: panic/unwrap in production path)
- non-exhaustive-public-api (future-proofing public API types)
- adr-doc-comments (doc convention: ADR references in new modules)
- ssh-session-recv-stub-doc (documentation: mark stubs as planned)
2026-06-08 04:35:52 +00:00
glm-5.1 9d50082a49 tasks: mark all 12 Phase 1 core tasks as completed 2026-06-07 16:47:06 +00:00
glm-5.1 22724228f8 Extract SshInterface from ServerHandler, add RawFramingInterface stub
- SshInterface implements Interface trait with accept() method
- SshSession implements InterfaceSession trait (stub for call protocol events)
- RawFramingInterface is type-only stub (Phase 4+ for DNS, WebTransport)
- TransportKind consolidated into transport module with Display, PartialEq, Eq
- ListenerConfig gains interface_kind field for (Transport, Interface) pairs
- SshInterface wraps existing russh handler logic (SshHandler)
- Auth delegation through IdentityProvider (not embedded in SshInterface)
- Channel routing through session to Layer 3 (forwarding policy)
- Server accept loop uses (Transport, Interface) pairs

Per ADR-026: SSH is Layer 2, not Layer 1. This is the highest-risk Phase 1
task, implementing the Interface trait to separate transport from interface.
2026-06-07 16:24:31 +00:00
glm-5.1 bd38c94cae Merge branch 'feat/core/napi-reload-api' 2026-06-07 15:30:51 +00:00
glm-5.1 88a875241a Add NAPI reload API for DynamicConfig and ForwardingPolicy
- Add reloadAuth(), reloadForwarding(), reloadAll() methods to AlknetServer
- Add NAPI type definitions: AuthConfigNapi, ForwardingPolicyConfig, ForwardingRuleConfig
- Refactor NapiServerHandler to use ArcSwap<DynamicConfig> for atomic config swaps
- Add ConfigReloadHandle::dynamic_arc() accessor for sharing ArcSwap between NAPI and accept loop
- Add ipnetwork dependency to alknet-napi for TargetPattern CIDR parsing
- Add builder functions for AuthPolicy and ForwardingPolicy from NAPI config types
- All swaps are atomic via ArcSwap per ADR-030
2026-06-07 15:30:38 +00:00
glm-5.1 f62f8dfaf1 feat: define Interface trait and InterfaceConfig types (core/interface-trait-definition)
Add Layer 2 interface abstraction per ADR-026:
- Interface trait with accept() and associated Session type
- InterfaceConfig enum with Ssh and RawFraming variants
- SshInterfaceConfig with auth, forwarding, host_key fields
- RawFramingConfig (minimal, no SSH-specific config)
- InterfaceSession trait with recv()/send() producing InterfaceEvent frames
- InterfaceEvent wraps EventEnvelope with optional Identity
- Resolves OQ-IF-01: every session produces EventEnvelope frames
  via InterfaceSession, making Layer 3 interface-agnostic
- Valid (Transport, Interface) pair enumeration with
  TransportKindBase and is_valid_pair validation function
- Module re-exported from lib.rs
2026-06-07 15:27:51 +00:00
glm-5.1 de6e0795fd Merge branch 'feat/core/config-identity-provider-into-handler' 2026-06-07 15:12:53 +00:00
glm-5.1 fe53300956 feat(core): wire IdentityProvider and ForwardingPolicy into ServerHandler
- Change ServerHandler to hold Arc<dyn IdentityProvider> instead of Box<dyn IdentityProvider>
- Refactor Server::new() to use StaticConfig::from_serve_options() producing (StaticConfig, DynamicConfig)
- Remove duplicate parse_proxy_config from serve.rs (now in static_config.rs)
- Add with_identity_provider() accepting Arc<dyn IdentityProvider>
- Add integration tests for DynamicConfig reload and ForwardingPolicy deny
- Add test for custom IdentityProvider injection via with_identity_provider
- Move parse_proxy_config tests to static_config.rs module
2026-06-07 15:12:38 +00:00
glm-5.1 f19e7675ac feat(core): implement OperationEnv local dispatch, EventEnvelope, and frame encoding
Add local dispatch for OperationEnv with invoke() method, EventEnvelope
wire format struct, 4-byte BE length-prefixed frame encoding/decoding,
PendingRequestMap for call/subscribe correlation, call protocol event type
constants, and default /services/list and /services/schema operations.
2026-06-07 15:05:11 +00:00
glm-5.1 ee1cee6004 Merge branch 'feat/core/forwarding-policy' 2026-06-07 14:48:00 +00:00
glm-5.1 9478e2911d feat(core): implement ForwardingPolicy with rule-based allow/deny
Add ForwardingPolicy, ForwardingAction, ForwardingRule, and TargetPattern
types in config/forwarding.rs. Implement policy evaluation with first-match
wins semantics, principal and transport matching, CIDR and glob patterns.

Modify ServerHandler to check ForwardingPolicy before proxying in
channel_open_direct_tcpip. Reserved alknet-* destinations bypass policy.
Preserve existing behavior with default allow_all() policy.
2026-06-07 14:47:44 +00:00
glm-5.1 d651602bce Merge branch 'feat/core/operation-context-registry' 2026-06-07 14:44:38 +00:00
glm-5.1 0d6f94c24c feat(core): implement OperationContext, OperationRegistry, and OperationSpec 2026-06-07 14:44:26 +00:00
glm-5.1 85f798f611 Implement AuthProtocol irpc service behind feature flag
Add AuthProtocol enum (VerifyPubkey, VerifyToken, ReloadKeys, CheckAccess),
AuthResult enum (Ok(Identity), Denied(String)), and AuthServiceImpl
wrapping ConfigIdentityProvider via ArcSwap<DynamicConfig>. All gated
behind the irpc feature flag per ADR-028.
2026-06-07 14:42:12 +00:00
glm-5.1 92a307fd03 Merge branch 'feat/core/multi-transport-listeners' 2026-06-07 14:25:35 +00:00
glm-5.1 851cf1bdab feat(core): implement multi-transport listeners with ListenerConfig and Vec<ListenerConfig>
- Add ListenerConfig struct with transport_kind, listen_addr, per-transport config
- Add Dns and WebTransport variants to TransportKind (tags only, no behavior)
- Add .listeners() builder method to ServeOptions for multi-listener config
- Keep .transport_mode() backwards compatible (creates single-element listeners vec)
- Update Server::run() to use listeners from Server struct (first listener)
- Add Server::listeners() accessor for multi-transport listener configs
- Update StaticConfig to support listeners field, converted from ServeOptions
- All listeners share Arc<ArcSwap<DynamicConfig>>, ConnectionRateLimiter, and IdentityProvider
- Graceful shutdown terminates accept loop via existing shutdown signal
- TOML [[listeners]] array-of-tables syntax supported via ListenerConfig in StaticConfig
- Add comprehensive tests for ListenerConfig, multi-listener ServeOptions, Server creation
2026-06-07 14:25:23 +00:00
glm-5.1 c2a3ee39d4 Merge branch 'feat/core/identity-type-provider' 2026-06-07 14:21:32 +00:00
glm-5.1 c64dbd19d5 feat(core): implement Identity, IdentityProvider trait, and ConfigIdentityProvider
Add Identity struct with id/scopes/resources fields and IdentityProvider
trait with resolve_from_fingerprint/resolve_from_token methods. Implement
ConfigIdentityProvider reading from ArcSwap<DynamicConfig.auth> for
fingerprint-based key lookups. Delegate ServerHandler::auth_publickey()
through IdentityProvider instead of direct AuthPolicy access. Store
authenticated Identity in the handler for use by ForwardingPolicy.
2026-06-07 14:21:14 +00:00
glm-5.1 73375e8a97 Add ConfigServiceImpl and ConfigProtocol irpc enum behind feature flag
ConfigServiceImpl wraps ArcSwap<DynamicConfig> providing forwarding_policy(),
rate_limits(), and reload() methods for direct use (always available).
ConfigProtocol enum (GetForwardingPolicy, GetRateLimits, ReloadForwarding,
ReloadRateLimits) is gated behind the irpc feature flag per ADR-030.
2026-06-07 14:18:01 +00:00
glm-5.1 ee1b3f3819 feat(core): implement StaticConfig/DynamicConfig split with ArcSwap hot-reload
Split alknet-core configuration into StaticConfig (immutable after startup)
and DynamicConfig (hot-reloadable at runtime via ArcSwap).

- Add StaticConfig struct in config/static_config.rs with all fields per ADR-030
- Add DynamicConfig struct with AuthPolicy, ForwardingPolicy, RateLimitConfig
- Add ForwardingPolicy with allow_all()/deny_all() defaults (ADR-031)
- Add ConfigReloadHandle with reload() method for runtime config updates
- Replace Arc<ServerAuthConfig> with Arc<ArcSwap<DynamicConfig>> in ServerHandler
- Add config_reload_handle() to Server for obtaining reload handles
- Add AuthPolicy with authenticate_publickey/authenticate_certificate methods
- All existing tests pass with the new config structure
- Default DynamicConfig produces identical behavior to current code
2026-06-07 14:03:46 +00:00
glm-5.1 a7f0dcdeb9 tasks: decompose Phase 1 core modifications into 12 atomic implementation tasks
Phase 1 of the integration plan modifies alknet-core to support the
architectural changes from Phase 0 ADRs and specs. Decomposed into
dependency-ordered tasks across config split, identity, forwarding
policy, OperationEnv, interface abstraction, and NAPI reload API.

Critical path: config-split → identity → forwarding → wire-into-handler
→ interface-trait → ssh-interface-extraction → review.

Two highest-risk tasks (interface-trait-definition, ssh-interface-extraction)
are split from §1.8 per the integration plan's note that it may need
sub-phases. OperationEnv is split into types and runtime per Phase 1
local-dispatch-only constraint.
2026-06-07 13:29:58 +00:00
glm-5.1 9ab789ec5f tasks: mark all 6 remaining architecture tasks as completed with notes and summaries 2026-06-07 12:25:29 +00:00
glm-5.1 d3633b7839 docs: complete Phase 0 architecture — spec updates, review fixes, and link portability
Update four existing specs (overview, server, napi-and-pubsub, call-protocol) to
reflect Phase 0 decisions: three-layer model, IdentityProvider, ForwardingPolicy,
OperationEnv, static/dynamic config split. Review all 9 Phase 0a ADRs (026-034)
for consistency. Fix 4 critical issues from architecture review: missing OQ-SVC-05
in open-questions.md, deprecated hub terminology, undefined AuthService and noq
terms. Replace inline OQ text with cross-references per format rules. Add
ConfigServiceImpl definition to configuration.md. Port absolute workspace paths
to project-relative links by copying referenced docs (feasibility, certbot,
fail2ban, event_source_types) into docs/research/.
2026-06-07 11:27:52 +00:00
glm-5.1 835724d087 tasks: clarify phase boundaries in remaining task descriptions
The remaining task descriptions implied that downstream concerns
(StorageIdentityProvider, irpc service layer, agent services, multi-node
deployment) already exist. Updated to clearly distinguish:

- spec-update-server: Phase 1 ships ConfigIdentityProvider, not irpc auth
- spec-update-call-protocol: Phase 1 is local dispatch only; irpc and remote
  dispatch are contracted for later. Agent services are downstream concerns.
- spec-update-overview: Note which crates exist now vs which are Phase 2+ contracts
- review-spec-foundation: Add phase boundary check to acceptance criteria
2026-06-07 10:40:48 +00:00
glm-5.1 e7941da04a docs: clarify phase boundaries — Phase 1 vs downstream concerns
The architecture specs were implying that StorageIdentityProvider, irpc
service implementations, and application services (agent, Docker, etc.)
already exist. This commit makes the phasing explicit:

- services.md: deployment topology now clearly labels 'Current (Phase 1)'
  vs 'Future (Phase 2+)', notes that application services are downstream
- identity.md: StorageIdentityProvider labeled 'Future — Phase 2+',
  clarifying alknet-storage doesn't exist yet
- storage.md: adds phase note that the crate hasn't been built yet,
  StorageIdentityProvider is a future impl
- ADR-028: ConfigAuthService is Phase 1 path, StorageAuthService is
  Phase 2+ contract
- call-protocol.md: Agent Service Pattern section explicitly framed as
  a downstream application concern, not a core requirement
2026-06-07 10:29:52 +00:00
glm-5.1 19b3d3a078 docs: write Phase 0 architecture foundation — ADRs 026-034, spec docs, and task updates
Phase 0a — ADRs (9 new):
- ADR-026: Transport/interface separation (three-layer model)
- ADR-027: Crate decomposition (core, secret, storage, flowgraph, napi, CLI)
- ADR-028: Auth as irpc service (AuthProtocol behind feature flag)
- ADR-029: Identity as core type (Identity + IdentityProvider in alknet-core)
- ADR-030: Static/dynamic config split (ArcSwap, ConfigReloadHandle)
- ADR-031: Forwarding policy (rule-based allow/deny, TransportKind-aware)
- ADR-032: Event boundary discipline (domain, irpc, call protocol boundaries)
- ADR-033: OperationEnv universal composition (three dispatch paths)
- ADR-034: Head/worker terminology (replace hub/spoke)

Phase 0b — New spec documents (7):
- identity.md, services.md, interface.md, configuration.md,
  storage.md, flowgraph.md, secret-service.md

Updated existing docs:
- auth.md: reference identity.md for canonical definitions, add AuthProtocol
- open-questions.md: resolve OQ-12, OQ-16, OQ-18, OQ-22, OQ-23-25
- README.md: add all new docs, ADRs 026-034

Marked 19 architecture tasks as completed.
2026-06-07 09:32:58 +00:00
glm-5.1 84f16d66e7 tasks: decompose Phase 0b spec documents and Phase 0c review
Add 15 new tasks under tasks/architecture/ for Phase 0b (spec writing)
and Phase 0c (review):

Phase 0b — New specs (6):
  - spec-configuration: promote from research, cleanup, align with ADRs
  - spec-identity: carry from auth.md + services.md, canonical Identity
  - spec-secret-service: from research/services.md SecretProtocol
  - spec-storage: from research/storage.md, contract-level
  - spec-flowgraph: from research/flow.md, pure computation crate
  - spec-interface: new Layer 2 spec (highest risk new spec)
  - spec-services: irpc service layer + OperationEnv (broadest scope)

Phase 0b — Spec updates (6):
  - spec-update-overview: add crate structure, Layer 3, services
  - spec-update-auth: IdentityProvider vs AuthService relationship
  - spec-update-call-protocol: OperationEnv dispatch paths
  - spec-update-server: DynamicConfig, ForwardingPolicy, IdentityProvider
  - spec-update-napi: reload API, call protocol references
  - spec-update-open-questions: resolve OQs per ADR decisions

Phase 0b — Assembly (1):
  - spec-update-readme: add new docs and ADRs to tables

Phase 0c — Review (1):
  - review-spec-foundation: validate consistency checklist

Generation structure (6 total):
  Gen 1: 6 independent ADRs (parallel)
  Gen 2: adr-027, adr-028 (depend on adr-029)
  Gen 3: adr-033 + 6 spec docs + open-questions update (parallel)
  Gen 4: adr review + interface/services specs + 4 spec updates
  Gen 5: call-protocol update + readme update
  Gen 6: spec review
2026-06-07 09:01:01 +00:00
glm-5.1 5c820a41e9 tasks: decompose Phase 0a ADR foundation and mark prior tasks completed
Add 10 new tasks under tasks/architecture/ for Phase 0a (ADR writing):
- 9 ADR tasks (026-034) with dependency-ordered structure
- 1 review checkpoint task before Phase 0b spec writing

ADR dependency graph (3 generations):
  Gen 1 (parallel): 026, 029, 030, 031, 032, 034
  Gen 2 (depends on 029): 027, 028
  Gen 3 (depends on 027+028): 033
  Gen 4: review checkpoint

Also mark all 34 prior implementation tasks as completed — they
were finished but still showing as pending in the taskgraph.
2026-06-07 08:55:33 +00:00
glm-5.1 6db1266672 docs: fix inconsistencies in architecture specs
- Replace hub/spoke with head/worker terminology in call-protocol.md,
  auth.md, open-questions.md, napi-and-pubsub.md
- Update operation paths from /{spoke}/{service}/{op} to
  /{node}/{service}/{op} throughout call-protocol.md
- Unify Identity struct: auth.md already had {id, scopes, resources},
  add note clarifying this is canonical (vs research/services.md which
  used {node_id, fingerprint, scopes})
- Update integration-plan.md inconsistencies section to track what's
  been fixed (hub/spoke, identity model) and expand service naming
  to include external services
- Update call-protocol.md last_updated date

ADRs are intentionally left unchanged as historical records.
2026-06-07 07:50:00 +00:00
glm-5.1 69d232fda7 docs: add integration plan for services, pubsub, and operations
Organizes findings from the research phase (core, services, configuration,
storage, flow) into an actionable phased plan covering:

- Transport/Interface/Protocol three-layer model
- OperationEnv as universal composition mechanism (not replaced by irpc)
- Phase 0: Architecture foundation (9 ADRs, ~10 spec docs)
- Phase 1: Core modifications (config split, identity, forwarding, auth,
  OperationEnv, interface abstraction)
- Phase 2: External crates (alknet-secret, alknet-storage, alknet-flowgraph)
- Phase 3: Integration and wiring
- Phase 4: Advanced features (DNS, WebTransport, app services)

Key clarifications: irpc services are one dispatch backend for OperationEnv,
not a replacement for it. DNS control channel is a (DNS transport, raw framing
interface) pair, not SSH-over-DNS. Call protocol and irpc operate at different
scope boundaries within Layer 3.
2026-06-07 07:28:05 +00:00
glm-5.1 6f9b0c7f20 docs: add operation context, handler environment, and adapter patterns to services.md
Document the OperationContext (request_id, identity, metadata, env, trusted),
OperationEnv (namespaced callables for handler composition), ResponseEnvelope
pattern, and how MCP/OpenAPI adapters map to the irpc service model.
2026-06-06 16:44:33 +00:00
glm-5.1 d291a485f0 docs: refactor hub/spoke to head/worker, add service layer and HD key derivation
- Replace hub/spoke terminology with head/worker throughout all research docs
- Add irpc service layer architecture (AuthProtocol, SecretProtocol,
  ConfigProtocol, StorageProtocol)
- Add BIP39/SLIP-0010 HD key derivation for secrets management
- Add event boundary discipline (domain events vs integration events)
- Add application services layer (Docker, Node, Wallet, Proxy, Compute)
- New docs/research/services.md defining irpc service protocols
- Update core.md with service layer section and head/worker model
- Update configuration.md to delegate auth to AuthService (irpc)
- Update storage.md with secrets/key derivation and event boundaries
- Update flow.md with event boundary decision and cross-references
2026-06-06 15:33:35 +00:00
glm-5.1 2315a211ff docs: move research specs to docs/research/ 2026-06-06 06:20:50 +00:00
glm-5.1 28f2edec3e docs: add research specs for core, storage, and flowgraph crates 2026-06-06 05:26:24 +00:00
glm-5.1 596c89ce24 refactor!: rebrand wraith to alknet
Rename all crates, CLI commands, constants, type names, doc comments,
and documentation from wraith to alknet. Includes wire-protocol changes:
ALPN wraith-ssh -> alknet-ssh, reserved destination prefix wraith- ->
alknet-, SSH auth username wraith -> alknet.
2026-06-05 10:04:32 +00:00
glm-5.1 af7f4d0006 docs: add auth, call protocol architecture specs and ADRs 023-025
Unified authentication (ADR-023): SSH and WebTransport auth share the same
Ed25519 key material. Token auth uses signed timestamps verified against the
same authorized_keys set. IdentityProvider trait decouples core from identity
storage.

Bidirectional call protocol (ADR-024): Generalizes control channel (ADR-018)
to support hub→spoke and spoke→hub calls. Operation paths use /{spoke}/{service}/{op}
format for three-level routing. EventEnvelope wire format, five call events,
PendingRequestMap for correlation.

Handler/spec separation (ADR-025): Downstream consumers register operations
without modifying core. OperationRegistry maps paths to specs + handlers.
Service discovery via /services/list and /services/schema.

Resolves OQ-17 (transport-aware auth), OQ-21 (spoke routing), OQ-CFG-04 and
OQ-CFG-06 (WebTransport auth and transport-aware auth layer). Adds OQ-18
through OQ-22 for remaining open questions.
2026-06-05 08:19:41 +00:00
glm-5.1 41062d810e docs: add configuration architecture research
Explore static/dynamic config split, hot-reloadable auth via ArcSwap,
forwarding policy, multi-transport listeners, and config file format.
Documents three problems: no auth hot-reload, no forwarding access control,
no structured config beyond CLI flags.

Key findings:
- Static config (transport, TLS, host key) loaded once at startup
- Dynamic config (auth, forwarding, rate limits) reloadable via ArcSwap
- ForwardingPolicy with rule-based allow/deny, first-match evaluation
- Multi-transport: Server spawns Vec<ListenerConfig> sharing auth config
- WebTransport out of scope for now (requires separate auth model)
- Proposes ADR-020 (static/dynamic split), ADR-021 (forwarding policy),
  ADR-022 (multi-transport listeners)

Adds OQ-12 through OQ-17 to open-questions.md.
2026-06-04 09:40:58 +00:00
glm-5.1 5ffcf9232b feat(iroh): add from_endpoint constructors for shared iroh Endpoint
Enable running wraith alongside iroh-blobs, iroh-gossip, and iroh-docs
on the same QUIC endpoint (one connection per peer, multiplexed by ALPN).

- IrohTransport::from_endpoint(node_id, endpoint) for client-side shared endpoint
- IrohAcceptor::from_endpoint(endpoint) for server-side shared endpoint
- Export ALPN constant as IROH_ALPN for Router registration
- Add owned() method to track whether the endpoint was created internally
- Existing new()/bind() constructors unchanged (backwards compatible)
- Add tests for from_endpoint constructors and shared endpoint connectivity
2026-06-03 10:24:07 +00:00
glm-5.1 d85c882635 feat!: harden SSH server handler security
- Restrict auth methods to PUBLICKEY only (no none, password, hostbased,
  or keyboard-interactive advertised during negotiation)
- Log all denied channel types (session, x11, forwarded-tcpip) and
  dangerous request types (exec, shell, subsystem, pty, env, x11, agent)
- Explicitly reject all dangerous channel request handlers (exec, shell,
  subsystem, pty, env, x11, agent forwarding) with channel_failure
  responses instead of russh's default silent Ok(()) which leaves clients
  hanging and is a footgun if session channels are ever allowed
- Explicitly reject tcpip_forward, streamlocal_forward with logged warnings
- Log signal requests at debug level (harmless, no response needed)
- Override handlers in both core ServerHandler and NapiServerHandler
- Add tracing dependency to wraith-napi for security event logging
- Set preferred algorithms explicitly (russh::Preferred::DEFAULT which
  uses only modern KEX/cipher/MAC algorithms)
2026-06-03 09:04:01 +00:00
glm-5.1 a7595f1718 fix: update repo URLs from github.com/alkdev to git.alk.dev/alkdev 2026-06-03 06:45:22 +00:00
glm-5.1 37ff929a42 docs: add iroh and TLS NAPI examples to README 2026-06-03 06:30:39 +00:00
glm-5.1 150b1f3ae5 feat(napi): add TLS and iroh transport support to serve() and connect() 2026-06-03 05:58:05 +00:00
glm-5.1 053ace6fcc docs: add README, LICENSE files, and crate/module-level doc comments
Add top-level README.md with alpha status warning, quick start guide,
architecture overview, feature flags, transport modes, auth docs, and
Node.js API examples.

Add dual LICENSE-MIT and LICENSE-APACHE files.

Add comprehensive crate-level and module-level rustdoc to all three
crates (wraith-core, wraith, wraith-napi) and all public modules
(transport, client, server, auth, socks5, error). Add doc comments to
key public types (Transport, TransportAcceptor, ConnectOptions,
ClientSession, Server, ServeOptions, KeySource, ServerAuthConfig, etc).

Update Cargo.toml files with workspace-level package metadata
(version, edition, license, repository) and crate descriptions.
2026-06-02 22:03:10 +00:00
glm-5.1 f63589a5ca chore: complete review/complete-system — final review passed, all criteria met 2026-06-02 20:27:03 +00:00
glm-5.1 9b06f26a3c chore: complete review/server-and-client with fixes applied 2026-06-02 20:22:22 +00:00
glm-5.1 e49aef05d3 fix: wire channel proxy into handler, add client reconnection with backoff, fix ADR-006 violations
- handler.channel_open_direct_tcpip now proxies non-wraith channels via
  connect_outbound+proxy_channel instead of dropping them
- ClientSession.run() spawns reconnect monitor that detects handle closure,
  reconnects with exponential backoff (1s/2s/4s/8s/16s/30s cap),
  and re-registers remote port forwards
- Remove server-side logging of tunnel destinations (ADR-006 compliance)
- Remove debug-level logging of proxy targets in channel_proxy
2026-06-02 20:22:13 +00:00
glm-5.1 f057e868ce chore: complete Gen 8 + Gen 9 meta tasks (cli-layer, napi-layer, serve-function, serve-command) 2026-06-02 20:08:34 +00:00
glm-5.1 0fdb6cd782 feat(napi): implement serve() function with WraithServer, WraithServerStream, and ConnectionInfo
Expose NAPI serve() per ADR-016. WraithServer provides close() and
onConnection(callback) for receiving SSH channel streams from
incoming connections. Each connection produces a WraithServerStream
(Duplex-like read/write/close) with ConnectionInfo (remoteAddr,
transportKind). Supports TCP transport with optional authorizedKeys
and certAuthority auth. TLS and iroh transports return helpful errors
indicating future support.
2026-06-02 20:05:13 +00:00
glm-5.1 62d57dd477 Implement wraith serve CLI subcommand with clap
Add serve subcommand with all flags matching server.md CLI interface:
--key, --authorized-keys, --cert-authority, --transport, --listen,
--tls-cert, --tls-key, --acme-domain, --stealth, --proxy,
--iroh-relay, --max-connections-per-ip, --max-auth-attempts.

--key is required, --transport defaults to tcp, --listen defaults to
0.0.0.0:22. --stealth validates TLS transport. --acme-domain requires
acme feature flag. --transport iroh prints endpoint ID on startup.
Key inputs accept file paths. Errors reported to stderr with non-zero
exit code. Also adds acme feature flag and rustls-pemfile/rustls-pki-types
dependencies for TLS cert loading.
2026-06-02 12:28:37 +00:00
glm-5.1 c7b8c5c5e0 chore: complete meta/server-layer — all server module tasks done 2026-06-02 12:12:53 +00:00
glm-5.1 6297c07383 chore: fix clippy dead_code warning on handler.transport, update serve-loop task to completed 2026-06-02 12:11:54 +00:00
glm-5.1 32a8c9a725 Merge branch 'feat/server/serve-loop' 2026-06-02 12:04:09 +00:00
glm-5.1 373b053820 feat(server): implement serve loop, ServeOptions, graceful shutdown, and integration test
- Add ServeOptions struct with all CLI fields (key, authorized_keys, cert_authority,
  transport_mode, listen_addr, tls_cert, tls_key, acme_domain, stealth, proxy,
  iroh_relay, max_connections_per_ip, max_auth_attempts)
- ServeOptions::key/authorized_keys accept KeySource (file or in-memory)
- Server::new(opts) creates server with bound russh config, auth config, rate limiter
- Server::run(acceptor, endpoint_info) enters accept loop: rate limit check -> create
  handler -> russh::server::run_stream()
- Stealth mode integration: protocol detection before run_stream() on TLS connections
- Graceful shutdown: Server::shutdown() sends SSH disconnect, waits drain timeout,
  aborts remaining sessions
- SIGTERM/SIGINT handler on unix platforms
- iroh mode: prints endpoint ID on startup
- Integration test: start server, shutdown signal, verify clean exit
- Re-export Server, ServeOptions, ServeTransportMode, ServeError from lib.rs
2026-06-02 11:57:30 +00:00
glm-5.1 94feb5fdac feat(cli): implement wraith connect subcommand with clap derive
All CLI flags from client.md: --server, --peer, --transport (default tcp),
--identity, --socks5 (default 127.0.0.1:1080), --forward (repeatable),
--remote-forward (repeatable), --proxy, --iroh-relay, --tls-server-name,
--insecure. Env var defaults: WRAITH_SERVER, WRAITH_IDENTITY. Validates
--server required for tcp/tls, --peer required for iroh, --identity required.
Warns on --proxy with --transport tcp (ADR-019). Translates args to
ConnectOptions and calls ClientSession::new(opts).run().await. Errors to
stderr with non-zero exit.
2026-06-02 11:39:57 +00:00
glm-5.1 f13a1c985f Merge remote-tracking branch 'origin/feat/server/channel-proxy'
# Conflicts:
#	crates/wraith-core/src/error.rs
#	crates/wraith-core/src/server/mod.rs
2026-06-02 11:32:28 +00:00
glm-5.1 49fe2b699f Implement server channel proxy: direct, SOCKS5, and HTTP CONNECT outbound connections
- Add channel_proxy.rs with connect_outbound() supporting Direct, Socks5, and HttpConnect proxy modes
- Implement proxy_channel() with bidirectional copy between SSH channel and outbound TCP
- Channel errors close individual channels without affecting SSH session (ADR-006)
- Remove destination logging from handler to comply with ADR-006
- Add ForwardError to error.rs (was missing, needed by forward.rs)
- Fix TcpListener type annotation in forward.rs
- Add 11 unit tests: direct, SOCKS5 handshake, HTTP CONNECT, proxy rejection, unreachable targets
2026-06-02 11:24:32 +00:00
glm-5.1 365b11d19e Merge remote-tracking branch 'origin/feat/server/stealth-mode'
# Conflicts:
#	crates/wraith-core/src/error.rs
#	crates/wraith-core/src/server/mod.rs
2026-06-02 11:14:06 +00:00
glm-5.1 7dcf7502b7 feat(server): implement stealth mode protocol multiplexing (ADR-017)
Add stealth mode detection that peeks at the first bytes after TLS handshake
to determine SSH vs HTTP protocol. SSH connections proceed to russh handler;
non-SSH connections receive a fake nginx 404 response, making the server
indistinguishable from an ordinary HTTPS site to scanners and DPI systems.

- ProtocolDetection enum (Ssh, Http) for protocol classification
- detect_protocol() uses BufReader::fill_buf() to peek without consuming bytes
- send_fake_nginx_404() writes HTTP/1.1 404 + Server: nginx headers
- validate_stealth_config() enforces TLS transport requirement for stealth
- 17 unit tests covering SSH banner, HTTP, random data, and edge cases
2026-06-02 11:13:15 +00:00
glm-5.1 585913d3c8 Merge remote-tracking branch 'origin/feat/napi/connect-function'
# Conflicts:
#	crates/wraith-core/src/error.rs
2026-06-02 11:11:14 +00:00
glm-5.1 243243a82f Implement NAPI connect() function — single SSH channel as duplex stream
- Add WraithConnectOptions struct with napi fields: server, peer, transport,
  identity (string path or Buffer), tlsServerName, insecure, irohRelay, proxy
- Add WraithStream napi class wrapping SSH channel read/write halves via
  ChannelStream::into_stream() + tokio::io::split()
- Implement connect() async function: transport creation (tcp, tls), SSH client
  connection, authenticate, open direct_tcpip channel, return WraithStream
- Identity field accepts file path (string) or in-memory key data (Buffer)
- All Rust errors marshalled to JavaScript exceptions with descriptive messages
- Add ForwardError enum to wraith-core (required by forward.rs)
- Enable tls, iroh features on wraith-core dependency
- 7 unit tests for key source resolution and address parsing
2026-06-02 11:10:42 +00:00
glm-5.1 2ab5eeda53 Merge remote-tracking branch 'origin/feat/client/connect-options' 2026-06-02 11:07:54 +00:00
glm-5.1 128affd264 Implement ConnectOptions struct and ClientSession orchestration with graceful shutdown
Adds client/connect.rs with ConnectOptions (programmatic API per ADR-011),
ClientSession::new() for SSH session establishment, ClientSession::run()
for SOCKS5 + port forwards + shutdown, and graceful shutdown via
SIGTERM/SIGINT with SSH disconnect and 2s drain timeout.
2026-06-02 11:07:33 +00:00
glm-5.1 5a2b535605 Merge remote-tracking branch 'origin/feat/server/rate-limiting-and-logging'
# Conflicts:
#	crates/wraith-core/src/error.rs
#	crates/wraith-core/src/server/handler.rs
#	crates/wraith-core/src/server/mod.rs
2026-06-02 11:06:18 +00:00
glm-5.1 24b70f5651 Implement server rate limiting and fail2ban-friendly structured logging
Add ConnectionRateLimiter (HashMap<IpAddr, usize>) and AuthAttemptLimiter
with check/on_connect/on_disconnect and check/on_failure methods.
Integrate into ServerHandler with structured tracing::info! logging for
auth attempts, connection opened/closed events. No logging of tunnel
destinations per ADR-006. Also add ForwardError type and fix type
annotation in forward.rs to unblock compilation.
2026-06-02 11:02:55 +00:00
glm-5.1 f963898a05 Implement control channel routing for wraith-* reserved destinations (ADR-018)
- Add control_channel.rs with WRAITH_CONTROL_DESTINATION, WRAITH_PREFIX constants
- Add ControlChannelHandler trait and ControlChannelRouter for routing logic
- Add DuplexStream supertrait for Box<dyn> compatibility
- Server handler rejects wraith-* destinations when no handler configured
- Add ForwardError type to fix pre-existing compilation error
- Unit tests: reserved detection, non-reserved pass-through, prefix matching
2026-06-02 11:01:54 +00:00
glm-5.1 992d478630 Merge remote-tracking branch 'origin/feat/transport/acme-cert-provisioning' 2026-06-02 10:49:57 +00:00
glm-5.1 e3f33a24c3 Implement ACME/Let's Encrypt certificate provisioning (ADR-008)
Add AcmeCertProvider with domain-based and IP-based modes using rustls-acme.
AcmeTlsAcceptor::bind_acme() and TlsAcceptor::bind_acme() provide ACME-integrated
TLS acceptance with automatic cert renewal via background tokio task.
Feature-gated behind 'acme' (implies 'tls'). Unit tests for config construction;
integration test for LE staging marked #[ignore].
2026-06-02 10:49:32 +00:00
glm-5.1 5fec0b53d9 Merge remote-tracking branch 'origin/feat/client/socks5-server' 2026-06-02 10:49:20 +00:00
glm-5.1 2efd4cf7c5 Implement SOCKS5 server: local proxy forwarding through SSH channels
Convert socks5.rs to directory module with protocol parsing and server
implementation. Socks5Server binds to configurable address (default
127.0.0.1:1080), handles SOCKS5 handshake (no-auth), parses IPv4/IPv6/domain
addresses, and proxies bidirectionally via SSH direct_tcpip channels.
Domain names sent unresolved (SOCKS5h) to prevent DNS leaks (ADR-006).
No logging of request targets per privacy requirements.
2026-06-02 10:49:07 +00:00
glm-5.1 4e4afd5020 Merge remote-tracking branch 'origin/feat/client/port-forwarding'
# Conflicts:
#	crates/wraith-core/src/client/mod.rs
#	crates/wraith-core/src/lib.rs
2026-06-02 10:46:54 +00:00
glm-5.1 7336c0f13c feat(client): implement port forwarding — local (-L) and remote (-R) forwards
- PortForwardSpec parses -L/-R spec strings: bind_addr:bind_port:target_host:target_port
- LocalForwarder binds TcpListener, accepts connections, opens SSH direct-tcpip channel, proxies bidirectionally
- RemoteForwarder sends tcpip_forward request, handles forwarded-tcpip channel opens, connects local target, proxies bidirectionally
- Both forwarders run concurrently with SOCKS5 server via Arc<Mutex<Handle>>
- Connection errors close individual channels without affecting other forwards or SSH session
- ForwardError type added with display and source chaining tests
- Unit tests: spec parsing, local forward bind/accept, remote forward proxy bidirectional
2026-06-02 10:45:43 +00:00
glm-5.1 975778bfb1 Merge remote-tracking branch 'origin/feat/client/channel-manager' 2026-06-02 10:44:32 +00:00
glm-5.1 d6a49a07d7 implement ChannelManager with SSH session management, channel ops, and reconnection 2026-06-02 10:44:21 +00:00
glm-5.1 24b92227e7 Implement ServerHandler with auth delegation and channel dispatch
Convert server.rs to directory module (server/mod.rs + server/handler.rs).
ServerHandler implements russh::server::Handler with:
- auth_publickey() delegating to ServerAuthConfig with structured logging
- channel_open_direct_tcpip() routing wraith-* prefix to internal handler,
  stub for regular TCP proxy
- ProxyConfig/ProxyMode types for outbound proxy configuration
- Unit tests for auth delegation, reserved destination routing, and
  unknown channel type rejection
2026-06-02 10:40:05 +00:00
glm-5.1 bf8233af61 fix: add rand dev-dep, install rustls CryptoProvider in TLS tests, fix iroh OsRng import 2026-06-02 10:32:29 +00:00
glm-5.1 b3589a038e Merge remote-tracking branch 'origin/feat/transport/iroh-transport' into transport/trait-and-types
# Conflicts:
#	Cargo.lock
#	crates/wraith-core/Cargo.toml
2026-06-02 10:30:12 +00:00
glm-5.1 c3f5f3f504 Implement IrohTransport and IrohAcceptor (feature-gated iroh)
Add iroh QUIC P2P transport using tokio::io::join for stream duplexing
per ADR-003. Default relay is n0's https://relay.iroh.network/ (ADR-009).
Proxy URL passed to Endpoint::builder (ADR-010). Integration test marked
#[ignore] for CI since it requires iroh relay connectivity.
2026-06-02 10:29:40 +00:00
glm-5.1 b559e335d3 Implement server-side auth with ServerAuthConfig (Ed25519 keys + cert-authority) 2026-06-02 10:21:28 +00:00
glm-5.1 1054e3907e Merge remote-tracking branch 'origin/feat/transport/tls-transport' into transport/trait-and-types
# Conflicts:
#	crates/wraith-core/src/transport/tls.rs
2026-06-02 10:09:12 +00:00
glm-5.1 f6d4705632 Implement TlsTransport and TlsAcceptor with tokio-rustls (feature-gated tls) 2026-06-02 10:08:29 +00:00
glm-5.1 4052c4f19e fix: add ssh-key dev-dependency for server_auth tests 2026-06-02 10:08:11 +00:00
glm-5.1 eb032c87f1 Implement client-side SSH auth handler with ClientAuthConfig and ClientHandler 2026-06-02 10:03:56 +00:00
glm-5.1 b4f4f2ed8c Implement SSH key material loading with KeySource, load_private_key, load_public_keys, and CertAuthorityEntry 2026-06-02 09:52:39 +00:00
glm-5.1 b157ab3799 Implement TcpTransport and TcpAcceptor for plain TCP connections 2026-06-02 09:23:35 +00:00
glm-5.1 dddc6d7a4c Define Transport trait, TransportAcceptor trait, TransportInfo, and TransportKind types 2026-06-02 09:17:50 +00:00
glm-5.1 56d032afdb Define error types for transport, auth, channel, and config layers 2026-06-02 09:16:23 +00:00
glm-5.1 2bc15f1035 Initialize Cargo workspace with wraith-core, wraith, and wraith-napi crates
- Workspace root Cargo.toml with three crate members
- wraith-core: library with feature flags (tls, iroh, acme), core deps (russh, tokio, tracing, anyhow, thiserror, tokio-util), module skeleton (transport, client, server, auth, socks5, error)
- wraith: binary crate depending on wraith-core with clap derive
- wraith-napi: cdylib crate depending on wraith-core, napi, napi-derive
- .gitignore for target/ and node_modules/
2026-06-02 09:14:40 +00:00
glm-5.1 14dbd81195 Decompose architecture into 35 atomic tasks across 10 generations for implementation 2026-06-02 09:02:55 +00:00
glm-5.1 b5c59ef3bc fix: replace Deno/TypeScript residuals with Rust conventions in agent definitions 2026-06-02 08:19:22 +00:00
glm-5.1 af8e7e8b44 Review architecture specs, address critical/warning issues, mark reviewed
Address 5 critical and 7 warning issues from architecture review:
- Fix duplicate sentence in napi-and-pubsub.md server side section
- Add wraith- namespace reservation to server.md constraints (ADR-018)
- Document stealth mode TLS-only requirement in server.md
- Create ADR-019 for --proxy dual semantics (client vs server)
- Clarify NAPI connect() vs CLI wraith connect distinction
- Add SOCKS5h default as privacy design decision in client.md
- Expand reconnection section (always-on, re-register port forwards)
- Add graceful shutdown sections to client.md and server.md
- Specify OpenSSH key format for path-or-buffer inputs across all docs
- Resolve pubsub alternative approach ambiguity (ADR-018 is primary)
- Replace server.md handler impl block with behavioral description
- Standardize iroh endpoint ID terminology (base58-encoded)
- Remove iroh API implementation details from transport.md/server.md
- Add error handling pattern as cross-cutting concern in overview.md
- Update all document statuses from draft to reviewed
2026-06-02 07:44:42 +00:00
glm-5.1 13b0991fb8 Resolve all architecture open questions, add 13 ADRs, update specs
Resolved all 11 open questions based on project guidance:

Transport:
- OQ-01/OQ-07: ACME/Let's Encrypt with domain + IP paths (ADR-008)
- OQ-02: Default to n0 relay, --iroh-relay override (ADR-009)
- OQ-05: Transport chaining supported natively (ADR-010)

Client:
- OQ-06: Programmatic-first API, no ~/.ssh/config (ADR-011)

Server:
- OQ-04: Ed25519 + OpenSSH cert-authority, no password auth (ADR-012)
- OQ-08: fail2ban-friendly logging + built-in rate limiting (ADR-013)

TUN:
- OQ-03/OQ-09: Deferred entirely, recommend tun2proxy (ADR-014)
- tun-shim.md marked deprecated

NAPI:
- OQ-10: Expose both connect() and serve() (ADR-016)
- OQ-11: Use napi-rs for FFI bridge (ADR-015)

Additional ADRs created during review:
- ADR-006: No logging of tunnel destinations (was phantom reference)
- ADR-017: Stealth mode protocol multiplexing
- ADR-018: Control channel for pubsub over SSH

Fixed: ADR-002 status → Superseded, ADR-007 title typo,
WRAUTH_SERVER typo, ADR-005 stale wraith-tun refs,
undefined ACL feature removed from server.md,
--proxy semantic difference documented.
2026-06-01 17:31:28 +00:00
glm-5.1 dad8224686 Add architecture specification for wraith SSH tunnel tool
Docs:
- README.md: index with doc table, ADR table, lifecycle definitions
- overview.md: purpose, exports, dependencies, constraints
- transport.md: Transport trait, TCP/TLS/iroh implementations, stream join
- client.md: SOCKS5 server, port forwarding, channel manager, reconnection
- server.md: auth, channel handling, stealth mode, outbound proxy
- tun-shim.md: separate privileged process, virtual DNS, --unshare mode
- napi-and-pubsub.md: NAPI wrapper, pubsub event target adapter

ADRs:
- 001: Pluggable transport via AsyncRead+AsyncWrite trait
- 002: TUN shim as separate process
- 003: iroh stream via tokio::io::join
- 004: SSH runs over transport, not alongside
- 005: SOCKS5 as primary interface, TUN as add-on
- 006(007): NAPI exposes single duplex stream

Open questions: 11 items covering TLS certs, iroh relay defaults,
Windows TUN, auth expansion, NAPI surface, TCP reconstruction
2026-06-01 15:01:45 +00:00
glm-5.1 c1275e2dfd init 2026-06-01 14:41:07 +00:00