Files
2026-05-27 23:29:53 +01:00

6.7 KiB

Add @suaveplan/server-keys — full-parity port of the 18-bin CLI

Package: @suaveplan/server-keys Status: PROPOSED Type: migration (full parity with main) + enterprise stack additions

  • Spec delta: ./specs/server-keys/spec.md
  • Target path: packages/security/server-keys/

Why

Operator-facing CLI bundle for the Suaveplan server-key lifecycle: root + server keychain generation (with hierarchical ChainedKeySigner chains via @suaveplan/crypto-keys), encrypted vault persistence, key rotation, vault/key viewing, signed file packet preparation/serving/validation, and a license-key issuance bin (uses the just-shipped @suaveplan/license). Upstream at ../suaveplan/packages/server/server-keys/ ships 18 bin entry points + 3 command modules + a shared prompt utility (3,122 LOC total). This migration ports all 18 bins verbatim at the CLI-surface level so operator scripts that invoke create-root-keys, roll-server-keys-chain, prepare-file, etc. continue to work byte-compatibly.

Genesis enterprise stack layered on top: SuaveplanError-typed errors with a SERVER_KEYS.* code registry, Zod boundary validation for CLI options, OpenTelemetry spans on the long-running operations (file prep/serve/validate, keychain ops), sibling .md docs ≥200 words per implementation file, fast-check property tests where pure-data functions exist (packet manifests, key-chain encode/decode), and 100/100/100/100 coverage. Upstream uses @suaveplan/keys (the old umbrella package); genesis-side calls are re-pointed to @suaveplan/crypto + @suaveplan/crypto-keys (the post-split surface) without changing the wire formats.

What changes

Net-new package at 0.1.0, ships under packages/security/server-keys/. ADDED:

18 bin entry points (verbatim CLI surface)

  • Key + chain bins (@suaveplan/crypto-keys chain signer): create-root-keys, create-root-keys-chain, create-server-keys, create-server-keys-chain, roll-server-keys, roll-server-keys-chain, verify-key-chain
  • Viewer bins: view-keys, view-vault, view-public-key-file, view-chain-public
  • File transport bins (@suaveplan/packer + @suaveplan/storage): prepare-file, serve-file, validate-file, get-file-stats, validate-packet
  • License bin (@suaveplan/license): license — issues / validates / inspects software-license keys
  • Top-level dispatcher: suaveplan (single commander entry routing to all 17 sub-commands)

Internal command modules (the library surface the bins call into)

  • commands/keys/keys.ts — createRootKeysCommand, createServerKeysCommand, rollServerKeysCommand, createRootKeysChainCommand, createServerKeysChainCommand, rollServerKeysChainCommand, verifyKeyChainCommand, viewers
  • commands/files/files.ts — prepareFileCommand, validateFileCommand, getFileStatsCommand, validatePacketCommand
  • commands/files/serve-file.ts — serveFileCommand
  • commands/license/license.ts — licenseCommand (wraps @suaveplan/license LicenseManager)
  • prompt/prompt.ts — promptForPassword, promptForNewPassword (@inquirer/prompts)
  • run-function.ts — top-level error-handling wrapper for .action(...) callbacks

Enterprise stack (additive over upstream)

  • error-codes.ts — SERVER_KEYS_* code registry via defineCodes("SERVER_KEYS", [...]), ServerKeysError extends SuaveplanError<ServerKeysErrorCode>. Codes cover vault decrypt failures, password mismatch, missing root vault, chain verification failure, packet integrity failure, file IO failures, unknown command, plus license-bin pass-throughs.
  • Zod boundary schemas for every CLI option bag.
  • OpenTelemetry: counter server_keys.command_total{command}, histogram server_keys.command_duration_ms{command}, span per command.
  • LoggerLike from @suaveplan/types injectable through every command (defaults to console).
  • AbortSignal plumbing for long-running file ops.

Bin registration in package.json

The full 18-bin bin map matches upstream verbatim so bun link / npm install -g exposes every operator command. Names:

suaveplan, license, create-root-keys, create-server-keys, roll-server-keys,
create-root-keys-chain, create-server-keys-chain, roll-server-keys-chain,
verify-key-chain, view-keys, view-vault, view-public-key-file,
view-chain-public, prepare-file, serve-file, validate-file, get-file-stats,
validate-packet

Subpath exports

Library subpaths so downstream packages can call the command functions directly (e.g. test harnesses, integration tests): ./commands/keys/keys, ./commands/files/files, ./commands/files/serve-file, ./commands/license/license, ./prompt/prompt, ./error-codes, ./run-function.

Out of scope

  • Daemon / always-on serve-file mode. Upstream's serve-file is one-shot reconstruction; genesis preserves that. A long-running HTTP serve mode belongs in a separate @suaveplan/server-keys-http follow-up.
  • Re-implementing the upstream wire formats. The keychain encoding, packet header, and license payload formats all come from their respective packages (@suaveplan/crypto-keys, @suaveplan/packer, @suaveplan/license). server-keys is the CLI wrapper, not the format owner.
  • Cross-platform binary distribution. Bins run under Bun/Node; we do not ship pkg/nexe-style standalone binaries.
  • Telemetry exporter wiring. OTel instruments are registered against @opentelemetry/api; concrete exporter (OTLP/Prometheus/Jaeger) is the operator's choice.

Source mapping

Capability Upstream source Notes
18 bin entry points + commander routing ../suaveplan/packages/server/server-keys/src/bin/*.ts + bin/index.ts verbatim CLI surface
Key + chain commands (628 LOC) src/commands/keys/keys.ts re-pointed from @suaveplan/keys → @suaveplan/crypto-keys ChainedKeySigner
File transport commands (311 LOC) src/commands/files/files.ts + serve-file.ts uses @suaveplan/packer + @suaveplan/storage/storage-file
Password prompts src/prompt/prompt.ts @inquirer/prompts
License bin src/bin/license.ts + src/commands/license/license.types.ts wraps @suaveplan/license LicenseManager
runFunction error wrapper src/runFunction.ts verbatim
Enterprise audit (Zod, OTel, structured errors, 100% coverage, sibling .md) ../suaveplan/enterprise/server-keys.md all addressed
ServerKeysError + SERVER_KEYS_* code registry genesis-original genesis policy — upstream throws plain Error

Impact

Affected dependents

None today — net-new on genesis. First downstream will be operator scripts (out-of-repo) and CI workflows that issue/rotate server keys. The license bin transitively pulls in @suaveplan/license (shipped today).