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

91 lines
6.7 KiB
Markdown

# restore-crypto-opinionated-layer — build the missing modules in `@suaveplan/crypto`
**Packages:** `@suaveplan/crypto`
**Status:** PROPOSED
**Type:** feature (additive; no breaking changes to existing modules)
**Carved from:** `restore-crypto-keychain-packer` umbrella (2026-05-03)
**Depends on:** `restore-crypto-cleanup-duplicates` and `restore-crypto-fold-keys-vault` must land first
## Why
After slices 1 and 2, `@suaveplan/crypto` holds the keychain, derivation, bundles, domain-tags, authority shell, errors, and folded keypair / BIP39 / legacy-Vault surface. The big gap is the *behavioural* opinionated layer — the actual signing hierarchy, signed envelopes, and append-only structures that turn primitives into a coherent product. Without these modules, the package is a label without a substance.
This slice ships the seven missing modules:
1. `Authority` — concrete in-memory backend behind the existing interface; signs under a `DerivationCoordinate` slot, rejects revoked slots, enforces validity windows, zeroises on `dispose()`
2. `RootIdentity` / `ServerIdentity` and `createRoot` / `createServer` / `rollServer` / `revokeServer` — typed wrappers around the keychain pair and the hierarchy operations that were modelled by upstream `nx/libs/keys/src/lib/keys-common.ts`
3. `Vault` (three-regime) — replaces the transitional `legacy-vault` from slice 2 with the spec-defined three-regime serialisation: public bundle (parent-signed, plaintext), private-key blob (password-AEAD, rotatable via `changePassword` without re-derivation), vault payload (auth-box-sealed under keypair, parent-signed under `DOMAIN_VAULT_V1`)
4. `Packer` / `Unpacker` — schema-driven encrypt-and-sign envelope over `@suaveplan/bitpacker`; `issuedAt` + `nonce` for replay-window protection
5. `ChunkedPacker` / `ChunkedUnpacker` — per-chunk-signed P2P fragmentation; tampered chunks fail at reassembly
6. `RevocationList` — root-signed CRL; append-only; verify-against-anchor
7. `AuditLog` — append-only Merkle log; root-signed root; tamper-detection on past entries
8. `wire-format/` — eight schemas committed with golden-bytes KAT fixtures: `DERIVATION_COORDINATE_SCHEMA`, `KEY_SLOT_PRIVATE_SCHEMA`, `KEY_SLOT_PUBLIC_SCHEMA`, `VAULT_PAYLOAD_SCHEMA`, `PUBLIC_BUNDLE_SCHEMA`, `CHAIN_BUNDLE_SCHEMA`, `CRL_ENTRY_SCHEMA`, `AUDIT_ENTRY_SCHEMA`
Property-based round-trip tests using `fast-check` accompany every schema.
## What changes
### Added — `@suaveplan/crypto/src/`
- `authority/in-memory-authority/` — concrete `InMemoryAuthority` implementing the existing `Authority` interface
- `identity/root-identity/`, `identity/server-identity/`, `identity/operations/` — `createRoot`, `createServer`, `rollServer`, `revokeServer`
- `vault/vault.ts` (three-regime), `vault/vault.types.ts`, `vault/changePassword.ts`, `vault/rotateApplicationData.ts` — replaces `legacy-vault/`
- `packer/packer.ts` (encrypt-and-sign envelope), `packer/replay-window.ts`
- `chunked-packer/chunked-packer.ts`, `chunked-packer/reassembly.ts`
- `revocation/revocation-list.ts`
- `audit-log/audit-log.ts`, `audit-log/merkle.ts`
- `wire-format/{derivation-coordinate,key-slot-private,key-slot-public,vault-payload,public-bundle,chain-bundle,crl-entry,audit-entry}-schema.ts` (eight schemas)
- `test-fixtures/wire-format/*.bin` — eight golden-bytes KAT fixtures
- Co-located `.md` for every implementation file (≥ 200 words, basic + advanced examples, full API reference)
### Modified
- `vault/legacy-vault/` — deleted in this slice once the three-regime `Vault` ships and any internal callers migrate
- `crypto/src/index.ts` — re-exports the new modules
- `crypto/src/errors/codes/codes.ts` — add codes for `PACKER.*`, `CHUNK.*`, `CRL.*`, `AUDIT.*`, `VAULT.PAYLOAD_*`, `AUTHORITY.SLOT_REVOKED`, etc.
### Tests added
- Per-feature `*.test.ts` for happy-path + every documented failure mode
- Per-feature `*.spec-conformance.test.ts` for type-level + observability + lifecycle scenarios
- `tests/wire-format-kat.test.ts` golden-bytes assertion against every committed fixture
- `tests/property-roundtrips.test.ts` — `fast-check` property tests for every pack/unpack pair
- Tampered-vault, tampered-chunk, expired-key, revoked-key, replay-rejection scenarios each pinned by a named `it(...)`
## Out of scope
- `@suaveplan/crypto-cli` package — slice 4
- `@suaveplan/slsa` migration to `Authority` — slice 4
- Import-allowlist conformance gate — slice 4
- HSM / threshold / YubiKey backends for `Authority` (the *interface* allows them; concrete drivers are dedicated future changes)
## Source mapping
The modules in this slice fold the contents of `restore-crypto-keychain-packer/specs/crypto/spec.md` requirements 7 (`Vault`), 8 (`Packer`), 9 (`ChunkedPacker`), 11 (`RevocationList`), 12 (`AuditLog`), 13 (`Authority` concrete backend), 14 (`Hierarchical identity`), 18 (`Wire-format KAT vectors`), and 19 (`Property-based round-trip`).
| Requirement | Umbrella spec source | Notes |
|---|---|---|
| `InMemoryAuthority` | umbrella `### Requirement: Authority — signing abstraction over hierarchical identity` | Concrete backend behind existing interface |
| `RootIdentity` / `ServerIdentity` / hierarchy ops | umbrella `### Requirement: Hierarchical identity — Root and Server` | Verbatim |
| Three-regime `Vault` | umbrella `### Requirement: Vault — three-regime serialisation with BIP39 restore and arbitrary application data` | Replaces transitional legacy-vault |
| `Packer` / `Unpacker` | umbrella `### Requirement: Packer — encrypt-and-sign envelope` | Verbatim |
| `ChunkedPacker` / `ChunkedUnpacker` | umbrella `### Requirement: ChunkedPacker — per-chunk-signed P2P fragmentation` | Verbatim |
| `RevocationList` | umbrella `### Requirement: RevocationList — root-signed CRL` | Verbatim |
| `AuditLog` | umbrella `### Requirement: AuditLog — append-only Merkle log` | Verbatim |
| Wire-format KAT vectors | umbrella `### Requirement: Wire-format KAT vectors` | Eight golden-bytes fixtures |
| Property-based round-trip | umbrella `### Requirement: Property-based round-trip coverage` | fast-check |
## Verification approach
- 100/100/100/100 coverage on every new module
- Per-feature `it(...)` names match the `**Verified by:**` lines in the spec deltas
- KAT fixtures committed and asserted byte-for-byte on every CI run
- Property tests run 100+ iterations per pack/unpack pair
- `bun run check` clean across monorepo
- `bunx turbo lint typecheck test:coverage build --filter=@suaveplan/crypto` green
## Migration impact
- The transitional `vault/legacy-vault/` is deleted in this slice. Any internal code (no out-of-package consumer today) that imported from `@suaveplan/crypto/vault/legacy-vault` migrates to the three-regime `Vault` at `@suaveplan/crypto/vault`.
- No public API breaks for anything else.