Skip to content

feat(release): pin the root and publish the first keys.json - #241

Merged
Madraka merged 1 commit into
mainfrom
claude/pin-root-keys
Nov 15, 2026
Merged

Madraka merged 1 commit into
mainfrom
claude/pin-root-keys

Conversation

@Madraka

@Madraka Madraka commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

What

The owner's root ceremony is done (2026-11-15). This PR pins the root and publishes the first signed key list. Nothing else changes.

  • PINNED_ROOTS (packages/release-verify/src/trust.ts) pins cloudhal-root-2026a, Ed25519, /rtDvlSlCYV402NiA/7OOFk+ryBv4DIWmkqwRyrVzqw=. Both the map and the entry are frozen.
  • security/keys.json, security/keys.json.sig and security/keys.source.json are copied from the ceremony checkout, byte for byte, checked with cmp before the commit. Nothing was re-signed here.
    • keys.json: SHA-256 9d6030ce9e5101e101c358415e1d5157e2dbe08978c5fc233c2488ede1d51e7c, issuedAt 2026-11-15T07:00:45Z, expires 2027-11-15T07:00:45Z, signed by cloudhal-root-2026a.
    • keys.json.sig: SHA-256 8cfe247e1a124e3e20bb4d730ebe1892925f76ce8d8f96e0d3e16b8fd62f3d21, 64 bytes.
    • The list holds cloudhal-release-2026a (release, active, 2026-11-12 to 2027-11-12) and cloudhal-yank-2026a (yank, active, kCnR6ndVCEVQ+EoNDFsP9tKuScP6xB95emcQCzZsNG4=, 2026-11-15T00:00:00Z to 2027-11-12T00:00:00Z).
    • Biome reports no fixes for these files, so formatting never rewrites them.
  • docs/security/release-signing-keys.md:
    • The Root keys table gets the cloudhal-root-2026a row (since 2026-11-15), with hex, SHA-256 and the SPKI PEM for cross-checking, and a note about the first keys.json. The "None yet" line is gone.
    • The yank key section gets the cloudhal-yank-2026a row with its window, hex and SHA-256.
  • Tests:
    • release-verify/test/package.test.ts:
      • PINNED_ROOTS equals the doc's root rows, holds exactly cloudhal-root-2026a, and is frozen down to the entry;
      • the committed security/keys.json verifies with PINNED_ROOTS (at a fixed date inside its validity), its keys equal keys.source.json, and a flipped byte is refused;
      • the doc's yank-key row equals keys.json's yank key.
    • release-verify/test/trust.test.ts: the no-root refusal passes roots: {}, and a list from an unpinned root is still refused with the pinned default.
    • cli/test/deploy-release.test.ts: the "no root pinned" refusal passes trustRoots: {}, so it is still covered: it names the ceremony and fetches nothing.
  • Changeset: @cloudhal/release-verify patch.

Tests (one at a time; paused until the machine load fell below 6)

  • release-verify: 86 passed, 1 skipped.

  • cli:

    File Tests
    deploy-release 24
    release-keys 20
    release-trust-assets 4
    release-workflows 14
    release-bundle-verify 12
    release-bundle-publish 10
    yank-list-workflow 6
  • core-contracts release-schemas: 23.

  • docs: 41.

  • tsc for release-verify and cli, biome and size:check are clean.

After merge (owner and PM, per the runbook's First-time setup)

From this merge on, every release attaches the trust lists and refuses to publish until cloudhal.dev serves a yanked.json that verifies. Run these straight after the merge:

  • the Yank list workflow with first_run (step 8);
  • the one-time pnpm --filter @cloudhal/docs run deploy (step 9).

Refs #226, #227

🤖 Generated with Claude Code

The owner's root ceremony is done (2026-11-15).

- PINNED_ROOTS pins cloudhal-root-2026a (Ed25519,
  /rtDvlSlCYV402NiA/7OOFk+ryBv4DIWmkqwRyrVzqw=), frozen.
- security/keys.json, keys.json.sig and keys.source.json are the ceremony's
  files, byte for byte (never re-signed here): issuedAt 2026-11-15T07:00:45Z,
  the release key cloudhal-release-2026a and the yank key cloudhal-yank-2026a.
- The key doc gains the root row (with hex, SHA-256 and PEM) and the yank
  key's row; tests keep both equal to PINNED_ROOTS and to keys.json.
- A test verifies the committed keys.json with PINNED_ROOTS and refuses a
  flipped byte; the no-root refusals inject roots: {}.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Madraka <[email protected]>
@Madraka
Madraka merged commit 5a21bfd into main Nov 15, 2026
9 checks passed
@Madraka
Madraka deleted the claude/pin-root-keys branch November 15, 2026 07:27
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