Skip to content

feat(security): add_ssh_key generate=true — server-side ed25519 keygen#594

Draft
dawsontoth wants to merge 1 commit into
mainfrom
claude/add-ssh-key-generate
Draft

feat(security): add_ssh_key generate=true — server-side ed25519 keygen#594
dawsontoth wants to merge 1 commit into
mainfrom
claude/add-ssh-key-generate

Conversation

@dawsontoth

@dawsontoth dawsontoth commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Draft / prototype for #570. Part of the create-harper deploy-by-reference effort. This is the secondary SSH-key path — the default is the client-side-sealed token credential (HarperFast/harper#1778).

add_ssh_key generate=true (with key omitted): the node mints an ed25519 keypair, stores/replicates the private half through the existing write path, and returns the public_key for the caller to register (e.g. as a GitHub deploy key). The private key never has to travel from the client.

  • Backward-compatible: supplying key behaves exactly as before.
  • The "key or generate" invariant is enforced with a clear error.
  • Peers re-running the replicated op already carry key, so they never re-generate.

Where: security/sshKeyOperations.ts. Uses ssh-keygen on the node. Parse + oxlint + prettier clean.

Refs #570.

Related — deploy-by-reference effort

Prototype PRs: HarperFast/harper#1850 (deploy by_ref) · HarperFast/harper#1851 (deploy setup) · #594 (add_ssh_key generate) · HarperFast/create-harper#118 (create-harper scaffold)

Tracking issues: HarperFast/harper#1777 · HarperFast/harper#1778 · #570 · HarperFast/create-harper#117 · HarperFast/harper#641 (rollback)

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request adds support for generating an ed25519 SSH keypair on the server side when generate: true is specified, keeping the private key secure within the cluster. Feedback on these changes focuses on performance, reliability, and type safety: using asynchronous execFile instead of blocking execFileSync to keep the event loop responsive, explicitly disallowing conflicting request parameters while wrapping key generation in a try-catch block to handle errors securely, and using Object.assign to prevent a TypeScript compilation error on the replication response.

Comment thread security/sshKeyOperations.ts Outdated
Comment thread security/sshKeyOperations.ts Outdated
Comment thread security/sshKeyOperations.ts
Comment thread security/sshKeyOperations.ts Outdated
Comment thread security/sshKeyOperations.ts Outdated
Comment thread security/sshKeyOperations.ts Outdated
@claude

claude Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Reviewed; no blockers found. All prior findings addressed in d30fb7f.

`add_ssh_key generate=true` (with key omitted) mints an ed25519 keypair on the node (async ssh-keygen); the minted private key flows through the same seal-at-rest + replicate path (sealSSHKey) as a client-supplied key, returning public_key for the caller to register (e.g. a GitHub deploy key). The private key never travels from the client. generate and key are mutually exclusive; the origin strips generate before replicating so peers receive a plain (sealed) key add. ssh-keygen failure (incl. not on PATH) is wrapped in a ClientError (no key material).

integrationTests cover generate=true (mints, returns public_key, sealed on disk), generate+key (rejected), and neither (client error). Rebased onto main to integrate with encrypt-at-rest (#582). Relates to HarperFast/harper#1778.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dawsontoth
dawsontoth force-pushed the claude/add-ssh-key-generate branch from d30fb7f to 0067f29 Compare July 20, 2026 17:46
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