14 KiB
14 KiB
@suaveplan/server-keys - Operator-facing CLI bundle for the Suaveplan server-key lifecycle: 18 bins covering root + server keychain generation (including hierarchical ChainedKeySigner chains), encrypted vault persistence via @suaveplan/crypto-vault, key rotation, vault/key viewing, signed file packet preparation/serving/validation via @suaveplan/packer + @suaveplan/storage-file, and license issuance via @suaveplan/license. suaveplan-enterprise additions: SuaveplanError-typed SERVER_KEYS_* codes, OTel command counter + duration histogram, Zod boundary validation, injectable AbortSignal, LoggerLike injection, 100% coverage.
Operator-facing CLI bundle for the Suaveplan server-key lifecycle:
18 bins covering root + server keychain generation (including
hierarchical ChainedKeySigner chains via @suaveplan/crypto-keys),
encrypted vault persistence via @suaveplan/crypto-vault, key rotation,
vault / public-key / chain inspection, signed file packet
preparation / serving / validation via @suaveplan/packer, and license
issuance via @suaveplan/license. suaveplan-enterprise additions:
SuaveplanError-typed SERVER_KEYS_* codes, OTel command counter +
duration histogram, Zod-style input validation, AbortSignal
threading, injectable LoggerLike.
Documentation tree
- create-root-keys-chain — Commander entry point for the
create-root-keys-chainoperator command. Parses CLI flags, prompts for any required pas… - create-root-keys — Commander entry point for the
create-root-keysoperator command. Parses CLI flags, prompts for any required passwords… - create-server-keys-chain — Commander entry point for the
create-server-keys-chainoperator command. Parses CLI flags, prompts for any required p… - create-server-keys — Commander entry point for the
create-server-keysoperator command. Parses CLI flags, prompts for any required passwor… - get-file-stats — Commander entry point for the
get-file-statsoperator command. Parses CLI flags, prompts for any required passwords v… - index — Commander entry point for the
indexoperator command. Parses CLI flags, prompts for any required passwords via `@suav… - license — Commander entry point for the
licenseoperator command. Parses CLI flags, prompts for any required passwords via `@su… - prepare-file — Commander entry point for the
prepare-fileoperator command. Parses CLI flags, prompts for any required passwords via… - roll-server-keys-chain — Commander entry point for the
roll-server-keys-chainoperator command. Parses CLI flags, prompts for any required pas… - roll-server-keys — Commander entry point for the
roll-server-keysoperator command. Parses CLI flags, prompts for any required passwords… - serve-file — Commander entry point for the
serve-fileoperator command. Parses CLI flags, prompts for any required passwords via `… - validate-file — Commander entry point for the
validate-fileoperator command. Parses CLI flags, prompts for any required passwords vi… - validate-packet — Commander entry point for the
validate-packetoperator command. Parses CLI flags, prompts for any required passwords… - verify-key-chain — Commander entry point for the
verify-key-chainoperator command. Parses CLI flags, prompts for any required passwords… - view-chain-public — Commander entry point for the
view-chain-publicoperator command. Parses CLI flags, prompts for any required password… - view-keys — Commander entry point for the
view-keysoperator command. Parses CLI flags, prompts for any required passwords via `@… - view-public-key-file — Commander entry point for the
view-public-key-fileoperator command. Parses CLI flags, prompts for any required passw… - view-vault — Commander entry point for the
view-vaultoperator command. Parses CLI flags, prompts for any required passwords via `… - files — Local-packer file-transport commands:
prepareFileCommand,validateFileCommand,getFileStatsCommand, `validatePack…- files — Local-packer file-transport commands:
prepareFileCommand,validateFileCommand,getFileStatsCommand, `validatePack… - packet-io — Shared on-disk format helpers for the file-transport commands. Holds the canonical packet envelope `{ data, signature,…
- serve-file — Reconstructs the original file from a directory of prepared packets by verifying each packet's ed25519 signature + sha2…
- files — Local-packer file-transport commands:
- keys — Non-chain key-lifecycle commands for
@suaveplan/server-keys. These functions are the library surface every key/view b…- keys-chain — Hierarchical
ChainedKeySigner-backed key-lifecycle commands. Each chain command wraps the matching crypto-vault orche… - keys-io — Private I/O and orchestration-layer helpers shared by every public keys command. Extracted from
keys.tsto keep each… - keys — Non-chain key-lifecycle commands for
@suaveplan/server-keys. These functions are the library surface every key/view b…
- keys-chain — Hierarchical
- license — Wraps
@suaveplan/licenseLicenseManagerinto the five sub-commands the operator-facinglicensebin exposes: `keyg… - error-codes — Defines the stable
SERVER_KEYS_*error-code registry used throughout@suaveplan/server-keys. Each code is a namespa…- error-codes — Defines the stable
SERVER_KEYS_*error-code registry used throughout@suaveplan/server-keys. Each code is a namespa…
- error-codes — Defines the stable
- otel — Registers the OpenTelemetry counter and histogram that every CLI command in
@suaveplan/server-keysemits exactly once…- instruments — Registers the OpenTelemetry counter and histogram that every CLI command in
@suaveplan/server-keysemits exactly once…
- instruments — Registers the OpenTelemetry counter and histogram that every CLI command in
- prompt — Thin, test-injectable wrappers around
@inquirer/prompts' password prompt for the two interactive flows every server-k…- prompt — Thin, test-injectable wrappers around
@inquirer/prompts' password prompt for the two interactive flows every server-k…
- prompt — Thin, test-injectable wrappers around
- run-function —
runFunctionis the single wrapper every server-keys CLI bin uses for its commander.action(...)body. It standardis…- run-function —
runFunctionis the single wrapper every server-keys CLI bin uses for its commander.action(...)body. It standardis…
- run-function —
Install
bun add @suaveplan/server-keys
# or, to install all 18 bins globally:
bun link
Commands
| Bin | Purpose |
|---|---|
suaveplan |
Top-level dispatcher routing to the 17 sub-commands below |
create-root-keys |
Create root keychain (vault + signed public-key file) |
create-root-keys-chain |
Create root keychain with self-signed chain |
create-server-keys |
Derive a server keychain from a root vault |
create-server-keys-chain |
Derive a chained server keychain |
roll-server-keys |
Rotate a server keychain to currentVersion + 1 |
roll-server-keys-chain |
Rotate a chained server keychain to currentVersion + 1 |
verify-key-chain |
Verify a chain file against a trusted root file |
view-keys |
Decrypt a vault and print a keychain summary |
view-vault |
Print vault file metadata without decryption |
view-public-key-file |
Decode and print a signed public-key file |
view-chain-public |
Decode a public-key file with optional signature verification |
prepare-file |
Pack a file into signed packets under an output directory |
serve-file |
Reconstruct a file from prepared packets (byte-identical) |
validate-file |
Walk every packet in a prepared directory and verify integrity |
get-file-stats |
Print file packing statistics without packing |
validate-packet |
Validate a single packet against an explicit verify key |
license |
Generate / validate / parse / revoke software license keys |
Programmatic-API quick-start
import {
createRootKeysCommand,
createServerKeysCommand,
} from "@suaveplan/server-keys/commands/keys/keys";
import {
prepareFileCommand,
} from "@suaveplan/server-keys/commands/files/files";
import { serveFileCommand } from "@suaveplan/server-keys/commands/files/serve-file";
import {
keygen,
generate,
validate,
} from "@suaveplan/server-keys/commands/license/license";
import { runFunction } from "@suaveplan/server-keys/run-function";
// Provision keys
await createRootKeysCommand("rootpw1234", { output: "./keys" });
await createServerKeysCommand(
"./keys/root.vault",
"rootpw1234",
"serverpw1234",
{ output: "./keys" },
);
// Prepare + serve a file with cooperative abort
const ac = new AbortController();
await prepareFileCommand(
"./data.bin",
"./keys/server.vault",
"serverpw1234",
{ output: "./prepared", packetSize: 256 * 1024, signal: ac.signal },
);
await serveFileCommand("./prepared", {
output: "./reconstructed.bin",
signal: ac.signal,
});
// License lifecycle
const kp = await keygen("./lic/keys.json", 1);
const lic = await generate({
signingKeyPath: "./lic/keys.json",
productId: 42,
tier: 2,
expirationDays: 365,
});
const checked = await validate(lic.key, {
publicKeysPath: "./lic/public-keys.json",
});
// Top-level wrapper for custom CLI integrations
await runFunction("custom-cmd", async (signal) => {
// ...your work; OTel + exit(1)-on-fail handled for you
});
Modules
error-codes—SERVER_KEYS_*registry +ServerKeysError.otel/instruments— counter + histogram +recordCommand.run-function— top-level.action(...)wrapper with OTel + structured error + abort plumbing.prompt/prompt—promptForPassword,promptForNewPasswordwith injectable seam for tests.commands/keys/keys— non-chain keys commands.commands/keys/keys-chain— chain variants +verifyKeyChainCommand.commands/keys/keys-io— shared I/O- decryption helpers.
commands/files/files— local-packerprepare/validate/stats/validate-packet.commands/files/serve-file— reconstruction.commands/files/packet-io— packet wire format helpers.commands/license/license—keygen/generate/validate/parse/revoke.commands/license/hex— hex encode / decode helpers.
Architectural decisions
- Local packer for file-transport bins. Upstream's
prepare-file/serve-file/validate-file/get-file-stats/validate-packetare HTTP clients pointed at a separatefile-server. Ships these as local packers backed by@suaveplan/packer's whole-filePacker/Unpacker+ plain Nodefs. No network hop, no separate deployment dependency, byte-name stable manifest + packet artefacts. - suaveplan-native vault wire format. Vault and signed-public-key
files are NOT byte-compatible with the upstream
@suaveplan/keysBitPacker-based format — the crypto-vault orchestration is the format owner. A future@suaveplan/keys-migrationpackage will ship the conversion path. - Plain Node
fsinstead of@suaveplan/storage-filefor vault I/O. storage-file appends.data/.metaextensions to every key on write, which would force operator scripts to address artefacts byroot.vault.datainstead of the conventionalroot.vault. The CLI contract is byte-name-stable across upstream and suaveplan. - Vault sign slot = ed25519, license sign slot = secp256k1. The
license format requires secp256k1; the vault's sign slot is
ed25519. The license bin therefore uses its own
keygensub-command rather than trying to reuse the vault's signing key.