Files
alkssh/docs/research/vision.md
T
glm-5.3-flash e43d2d184d docs(research): sharpen the door principle — two directions, vanilla on the outside
Vision principle 2 extended: server = door for vanilla clients (vanilla
in, family out; primary current purpose git), client = door to vanilla
servers (family in, vanilla out — reverse-runner hub dials vanilla
sshd; runner stays vanilla by design). Type symmetry at the seam
(family-protocol types both directions, russh the vanilla side); honest
asymmetry recorded (server serves seam entries, client consumes family
types)
2026-10-26 15:52:34 +00:00

6.8 KiB

Vision

Status: Draft (phase 0 research).

What this is

alkssh is the alk family's SSH adapter: a thin wrapper around russh terminating the vanilla-ssh wire and bridging to/from alkcall channels (family ADR-003). It is the alkhttp-style adapter for the SSH protocol — the vanilla-ssh front door for vanilla clients, and the family's vanilla-ssh client where a family app dials an upstream SSH server.

The substance almost entirely exists in the family. What alkssh adds is the glue + the mapping:

  • vanilla ssh (ssh(1), git(1), sftp clients) connect to an alkssh endpoint as they would to any sshd;
  • each SSH channel type is mapped onto a family protocol half (see mapping-table.md);
  • identity arrives the same way it does everywhere else in the family: a verified SSH public key's fingerprint resolved through alkcall's IdentityProvider (see auth-bridge.md).

The alkforge-relevant property is exclusion: an alkforge ssh endpoint built with only the git feature is structurally incapable of serving a shell, tunnels, or socks. Every mapping is a cargo feature; unfeatured channel opens decline fail-closed (family ADR-003 decision 3). This is why alkssh leads alkforge's phase 0 — the adapter is glue, not protocol invention.

Guiding principles

  1. russh owns the SSH wire. No SSH framing is authored in-family (family ADR-003 decision 1). KEX, cipher negotiation, channel multiplexing, and userauth state machines come from russh; third- party-upstream posture applies (file asks upstream; never silently absorb a workaround).
  2. A door in both directions, vanilla on the outside. alkssh is a door for vanilla clients (server direction: vanilla in, family out — each channel served by a family seam entry; primary current purpose: git) and a door to vanilla servers (client direction: family in, vanilla out — the reverse-runner shape: a family hub dials vanilla sshd and the ops map family-side onto the same protocols, alktty for sessions, alktunnels for tunnels/-D legs, alkgit for upstream git, alkfs client later for sftp; the runner stays vanilla by design). Type symmetry at the seam: the family-facing surface speaks family-protocol types in BOTH directions; the vanilla side speaks russh. The asymmetry is honest and recorded: the server direction serves family seam entries; the client direction consumes family types. It carries no deployment policy: a downstream app (alkforge) embeds it, enables features, and brings identity/ACL configuration.
  3. Fail-closed everything. The feature graph, the auth-method disposition, and the channel-request disposition all default to a clean decline. Nothing is advertised that isn't served; nothing is half-served. Every decline path is contract territory and is tested.
  4. One seam per mapping. Each family protocol already exposes a generic duplex-stream or Connection serving entry (mapping-table.md); a russh channel's read/write halves plug in at exactly one point per mapping. No channel-type knowledge flows upstream into the protocol crates.
  5. Identity is the family's, not SSH's. SSH user names, ~/.ssh/ conventions, and password auth are not the alk family's identity model. A verified key's fingerprint → Identity via alkcall's IdentityProvider is the only resolution path; secrets an alkssh client holds come from alkvault-backed sources — vault-encrypted at rest, treated as bearer-token-class secret material — never env vars (family ADR-002 decision 5). The vault is a secret store on this path, not a key generator or key custodian.

Non-goals

  • Authoring SSH protocol machinery — no in-family framing, cipher, or KEX code, ever (russh upstream decides what SSH is).
  • Being an sshd. No local user accounts, no authorized_keys file semantics of the OpenSSH variety, no PAM-shaped anything. Deployment posture belongs to the embedding app.
  • Serving sftp — deferred to alkfs (family ADR-002); the subsystem decline is the placeholder contract.
  • A binary / CLI. Downstream apps embed the crate; there is no alkssh executable in this crate.
  • Password / keyboard-interactive auth for clients. The family identity model has no password concept; these methods decline server-side (see auth-bridge.md) and exist client-side only as non-goals until a consuming use case arrives.

Scope questions phase 0 must answer

These frame the research docs; each is a candidate open question for phase 1's open-questions.md:

  1. The alk/ssh ALPN's topology role — alkcall ADR-004 reserves alk/ssh → SshAdapter, ADR-034's channels table gives it stream_types [0, 1] ("SSH multiplexes internally, including its own control"), and ADR-009 sketches a browser-WASM route where the ALPN transports an SSH stream to an SshAdapter. But family ADR-003 describes alkssh terminating vanilla SSH at an edge. Whether alk/ssh carries raw vanilla-SSH bytes between alkssh instances (a relay leg), serves the browser route, or both — and how that interacts with ADR-042's "the hub never runs a handler for alk/ssh" relay ruling — is unresolved (see mapping-table.md §topology).
  2. russh pin — version, crypto-backend feature, and the RC-pinned transitive dependency situation (see russh.md).
  3. Feature names + graph — the session/tunnel/dynamic-forward/git/sftp naming and their independence (no feature implies another; flat until architecture says otherwise).
  4. Auth dispositions — which russh auth methods the server implements vs declines; the exact auth_publickey → fingerprint → identity contract; client-side vault-backed at-rest key handling (see auth-bridge.md).
  5. The mapping table details — per channel type and per request, the family seam, the parameter mapping, and the decline contract (see mapping-table.md); POC validation per pocs.md.

Resolution status (post-POC): question 4 is answered by POC-1/POC-2 evidence, question 5 by POC-3 (three mapping-row corrections recorded), and question 2's facts are verified (the pin decision itself is phase 1 ADR territory). Questions 1 (the alk/ssh topology) and 3 (feature naming) are phase 1 decisions, carried as seeded OQs / ADR territory per pocs.md §Sequencing and gates. A client-direction consumer pattern (hub-dials-runner) is extracted in reverse-runner.md and shapes the phase 1 client surface.

References

  • family ADR-003 (/workspace/@alkdev/alkfamily/docs/architecture/decisions/003-alkssh-russh-adapter.md)
  • family ADR-002 (alkforge; why the exclusion property matters)
  • family open-questions OQ-08 (partially resolved; remaining scope is this repo's phase 0)
  • russh.md, auth-bridge.md, mapping-table.md, pocs.md in this directory