# 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, not a backend.** alkssh speaks family-protocol types only at the mapped seams. 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