Skip to content

Resolve SSH relay review annotations and document the connect-token round trip - #322

Merged
dbmikus merged 3 commits into
dylan/no-ssh-keygen-yet-fixfrom
dylan/ssh-websocket-code-review
Aug 9, 2026
Merged

Resolve SSH relay review annotations and document the connect-token round trip#322
dbmikus merged 3 commits into
dylan/no-ssh-keygen-yet-fixfrom
dylan/ssh-websocket-code-review

Conversation

@dbmikus

@dbmikus dbmikus commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes out the #amika/annotate review annotations left on the SSH
relay diff (no-relay connect-token bridge, scpv2, managed sshd, and
state package), documents the connect-token round trip for future
readers, and folds this session's annotation-handling learnings back
into the agent docs.

Changes

Connect-token documentation

  • Add top-of-file comments to norelay/token.go and operations.go
    explaining how the sandbox-side verifier and writer fit into the
    full connect-token lifecycle (generation, hashing, delivery,
    rotation), cross-referencing each other and the control-plane spec.

Review annotation resolutions

  • amikad serve: replace the hardcoded MaxConnections: 64 with a
    configurable ServeOptions.MaxConnections and --max-connections
    flag, defaulting to the newly exported
    norelay.DefaultMaxConnections.
  • state package: document the amika-mono side of the scrub-manifest
    contract (manifest format, register-before-write guarantee, the
    control plane's fail-closed sudo scrub at snapshot time), and point
    SetConnectToken's call site at it.
  • /healthz: document why it isn't named /health (Kubernetes/Google
    liveness convention; the control plane's e2e checks already probe
    this path) and leave it as-is.
  • scpv2: update scpv2.go's doc comments to the current
    <name>.<id>.<environment>.amika alias shape
    (ssh.BuildSessionAlias), and note in scpv2_test.go why the test's
    stub alias fixture doesn't need to track that format.
  • managed sshd: add AMIKA_SSHD_USER (default amika) to make the
    managed account configurable for both the UID/GID lookup and the
    authorized_keys home path; multi-user support stays out of scope.
  • state package tests: add coverage for a symlinked ancestor
    directory, a corrupt or hostile on-disk manifest (invalid JSON,
    JSON null, duplicate/relative/self-referential entries), the
    sensitive file size cap, non-permission mode bits, out-of-range
    ownership, and a pre-cancelled context.
  • plumbing: drop the redundant Hidden: true on ssh-stdio-proxy
    since the parent plumbing command is already hidden.
  • secrets.go: replace the "split this file up" annotation with
    TODO(KAPRO-747) to track it as a standalone follow-up.

Agent docs

  • amika-annotations skill: add annotate to the built-in
    imperative-types table for free-form review questions/requests.
  • AGENTS.md: note that comments here sometimes point at amika-mono
    (the private control-plane monorepo) for protocol details owned by
    that side, and that it should be looked up as a sibling worktree
    rather than searched for in this repo.

Stack

  1. dylan/amika-cli-skill Add amika-cli skill documenting the CLI for agents #315
  2. dylan/ssh-impl-no-relay Add the amikad sandbox daemon and the no-relay WebSocket SSH path #316
  3. dylan/no-ssh-keygen-yet-fix Fix the managed sshd port, add amika scpv2, and scope SSH sessions per control plane #321
  4. dylan/ssh-websocket-code-review #THIS ← you are here

dbmikus added 3 commits August 8, 2026 21:39
Add top-of-file comments to norelay/token.go and operations.go
explaining how the sandbox-side verifier and writer fit into the
full connect-token lifecycle (generation, hashing, delivery, and
rotation), with cross-references to the control-plane repo's spec
doc and to each other. Plain file-header comments, not package
docstrings -- handler.go and command.go already own this package's
doc comment.
Work through the `#amika/annotate` questions and TODOs left across the
diff during review, one per touched spot:

- `amikad serve`: MaxConnections was hardcoded to 64 in the no-relay
  bridge's Config. Add `ServeOptions.MaxConnections` and a
  `--max-connections` flag, defaulting to the newly exported
  `norelay.DefaultMaxConnections` (still 64) rather than a duplicated
  literal.
- `SensitiveStore`/scrub manifest: answer "does scrubbing actually find
  and clean up these files?" by documenting the amika-mono side of the
  contract in package state's doc comment (manifest format,
  register-before-write guarantee, and the control plane's fail-closed
  sudo scrub at snapshot time), and pointing SetConnectToken's call site
  at it.
- `/healthz`: answer why it isn't named `/health` (Kubernetes/Google
  liveness convention; the control plane's own e2e checks already probe
  this exact path) and leave it as-is.
- `scpv2`: chase "are the v2 alias test strings still right?" back to
  its answer -- yes for the test (its stub alias is an independent
  fixture), but scpv2.go's own doc comments still described the
  pre-per-environment `<name>.<id>.amika` alias shape. Update them to
  `<name>.<id>.<environment>.amika` to match `ssh.BuildSessionAlias`.
- managed sshd: make the default account configurable via a new
  `AMIKA_SSHD_USER` environment variable (default "amika"), covering
  both the UID/GID lookup and the authorized_keys home path. Multi-user
  support stays out of scope, per the annotation.
- `state` package tests: answer "does this need more red-teaming?" by
  adding coverage for a symlinked ancestor directory (not just the leaf
  path), a corrupt or hostile on-disk manifest (invalid JSON, JSON
  `null`, duplicate/relative/self-referential entries), the sensitive
  file size cap, non-permission mode bits, out-of-range ownership, and a
  pre-cancelled context.
- `plumbing`: drop the redundant `Hidden: true` on `ssh-stdio-proxy`;
  the parent `plumbing` command is already hidden, so nothing under it
  surfaces via `--help` regardless of its own Hidden field.
- `secrets.go`: replace the "split this file up" annotation with
  `TODO(KAPRO-747)`, tracking the split as a standalone follow-up
  instead of folding it into this diff.
- amika-annotations: add `annotate` to the built-in imperative-types
  table. It showed up nine times in one diff as a free-form question or
  request and was handled by inference every time; codify it so future
  runs don't re-derive the same behavior.
- AGENTS.md: note that comments/docstrings here sometimes point at
  amika-mono (the private control-plane monorepo) for protocol details
  owned by that side. That content isn't in this repo's own specs/
  directory, which is numbered separately and OSS-only; look for
  amika-mono as a sibling worktree instead of grepping for those paths
  here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a64e1bd3d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +177 to +180
&serveOptions.MaxConnections,
"max-connections",
norelay.DefaultMaxConnections,
"maximum concurrent no-relay bridge sessions",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Forward the connection limit to the background daemon

When serve is invoked with both --bg and a non-default --max-connections, Serve branches to serveBackground before constructing the handler, and that function launches the child with only --port and --beta-no-relay. The child therefore silently uses the default limit of 64, so this newly advertised flag has no effect in background mode; include the selected limit in the child arguments.

Useful? React with 👍 / 👎.

}
uid, gid := -1, -1
if account, err := user.Lookup("amika"); err == nil {
if account, err := user.Lookup(username); err == nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the managed-user override to the sshd policy

When AMIKA_SSHD_USER is set to anything other than amika, this lookup and the authorized-keys ownership switch to the custom account, but RenderConfig still emits AllowUsers amika. The managed daemon consequently denies SSH logins as the selected account, making the override unusable; carry the managed username into the rendered policy instead of retaining the hard-coded allowlist.

Useful? React with 👍 / 👎.

HostPrivateKey: "/var/lib/amikad/ssh_host_ed25519_key",
HostPublicKey: "/var/lib/amikad/ssh_host_ed25519_key.pub",
AuthorizedKeys: "/home/amika/.ssh/authorized_keys",
AuthorizedKeys: "/home/" + username + "/.ssh/authorized_keys",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the selected account's actual home directory

For a managed account whose home is not /home/<username> (for example a service account with a home under /var/lib), user.Lookup succeeds but this constructs an unrelated authorized-keys path. prepareAuthorizedKeysDirectory then either fails because that directory is absent or installs keys outside the account's home; build the path from the looked-up account's HomeDir.

Useful? React with 👍 / 👎.

@dbmikus dbmikus changed the title Resolve review annotations on the SSH relay diff Resolve SSH relay review annotations and document the connect-token round trip Aug 9, 2026
@dbmikus
dbmikus merged commit 35551a5 into main Aug 9, 2026
@dbmikus
dbmikus deleted the dylan/ssh-websocket-code-review branch August 9, 2026 17:14
dbmikus added a commit that referenced this pull request Aug 10, 2026
Release amika@v0.14.0.

Changes since amika@v0.13.0:

Direct (no-relay) SSH transport:
- Define and tighten the no-relay SSH contracts and vertical-slice
  spec (fc01f30, 650b433, dac6b6d)
- Implement the local no-relay SSH path and fix its runtime lifecycle
  (d4bb156, 05c6df1)
- Add `amika scpv2` over the direct WebSocket transport (9dccbfd)
- Bind the managed sshd to a reserved loopback port (2e90dc6)
- Scope v2 SSH session config per control plane (c7063c7)
- Resolve SSH relay review annotations and document the connect-token
  round trip (#322)

SSH key handling:
- Harden authorized key handling and close an ownership race (b565213,
  f448546, 3fde13c)
- Add an amikad authorized-keys clear subcommand (0e2fa59)
- Add the amika secret ssh-key command group (#324)

Sandbox images:
- Build and package amikad into the base images (6279f28, f336617)
- Repin the reviewed amikad source as fixes landed (862cbbd, 4777f5c,
  f864496, a6a4c04)
- Add sandbox codev2 editor support (#325)

Testing and CI:
- Test snapshot scrubbing end to end (#323)
- Publish linux-vm Daytona snapshots from CI, with retries and paged
  state verification (930a99f, 5379037, 4e713a7)

Agent tooling:
- Add and narrow the amika-cli skill for agents (9b6be25, 8cfc32a)
- Add [release <symbol>] prefix and release trailers to the CLI release
  skill (59526b2)

Release-Component: amika
Release-Version: v0.14.0
dbmikus added a commit that referenced this pull request Aug 10, 2026
Releases the `amika` CLI at v0.14.0 and rolls that release into the
sandbox base image.

Two commits:

1. **`[release amika] Bump install.sh DEFAULT_VERSION to 0.14.0`** — the
public CLI release. Carries the `Release-Component` / `Release-Version`
trailers.
2. **`Set Amika base snapshot to install amika CLI v0.14.0 and repin
amikad`** — bumps `AMIKA_VERSION` to 0.14.0 in
`go/internal/sandbox/presets/base/Dockerfile` and repins
`AMIKAD_SOURCE_REF` from `9dccbfd` to `4c7b647` (current `main`).

The amikad repin matters on its own: the old pin predated the no-relay
connect-token work, so sandbox images were building an amikad without
the connect-token round trip, the sshd-manager fixes, or the state
contract additions. The new ref resolves through the module proxy the
builder stage's `go install` uses (`github.com/gofixpoint/amika/go
v0.0.0-20260810034344-4c7b647bbeb8`).

## Changes since amika@v0.13.0

**Direct (no-relay) SSH transport**
- Define and tighten the no-relay SSH contracts and vertical-slice spec
(fc01f30, 650b433, dac6b6d)
- Implement the local no-relay SSH path and fix its runtime lifecycle
(d4bb156, 05c6df1)
- Add `amika scpv2` over the direct WebSocket transport (9dccbfd)
- Bind the managed sshd to a reserved loopback port (2e90dc6)
- Scope v2 SSH session config per control plane (c7063c7)
- Resolve SSH relay review annotations and document the connect-token
round trip (#322)

**SSH key handling**
- Harden authorized key handling and close an ownership race (b565213,
f448546, 3fde13c)
- Add an amikad `authorized-keys clear` subcommand (0e2fa59)
- Add the `amika secret ssh-key` command group (#324)

**Sandbox images**
- Build and package amikad into the base images (6279f28, f336617)
- Repin the reviewed amikad source as fixes landed (862cbbd, 4777f5c,
f864496, a6a4c04)
- Add sandbox codev2 editor support (#325)

**Testing and CI**
- Test snapshot scrubbing end to end (#323)
- Publish linux-vm Daytona snapshots from CI, with retries and paged
state verification (930a99f, 5379037, 4e713a7)

**Agent tooling**
- Add and narrow the amika-cli skill for agents (9b6be25, 8cfc32a)
- Add `[release <symbol>]` prefix and release trailers to the CLI
release skill (59526b2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant