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-keyschain 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(singlecommanderentry 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, viewerscommands/files/files.ts—prepareFileCommand,validateFileCommand,getFileStatsCommand,validatePacketCommandcommands/files/serve-file.ts—serveFileCommandcommands/license/license.ts—licenseCommand(wraps@suaveplan/licenseLicenseManager)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 viadefineCodes("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}, histogramserver_keys.command_duration_ms{command}, span per command. LoggerLikefrom@suaveplan/typesinjectable through every command (defaults to console).AbortSignalplumbing 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-fileis one-shot reconstruction; genesis preserves that. A long-running HTTP serve mode belongs in a separate@suaveplan/server-keys-httpfollow-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).