gabriel / musehub public
verify-old-key-signatures.md markdown
58 lines 2.8 KB
Raw
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago

Ed25519 signature verification fails for commits signed with rotated keys

Background

muse verify reports "Ed25519 signature INVALID" for commits that were signed with a key that is no longer the active identity key. This surfaces after a key rotation or after ~/.muse/secrets/ is regenerated — the old signing key (d526dbdee171d299 in the observed case) is gone, so the verifier cannot check the signature even though the commit was legitimately produced.

The commits are not tampered with. The content, DAG structure, and object hashes are all intact. The failure is purely a key-lookup miss: the verifier finds a signature but cannot resolve the public key that produced it.

Problem

The current verifier treats "can't verify" as "INVALID", which is misleading. A signature from a retired key is not evidence of tampering — it is evidence of a key lifecycle event. Logging it at the same severity as a genuine integrity violation creates false-positive noise and may erode trust in the audit trail.

There are two related questions to resolve:

  1. Should muse verify sweep prior HD-derived key paths when the current active key doesn't match the embedded signer_public_key? A commit signed at HD index n is still verifiable if we re-derive the key at that index from the root mnemonic. This would allow full provenance verification across key rotations without any schema changes.

  2. Should the error message be tiered? A signature whose public key is simply not found (key retired / mnemonic unavailable) should read differently from a signature whose public key is found but the bytes don't match (genuine tampering). The former is an audit gap; the latter is a security alert.

Goal

muse verify produces accurate, actionable output:

  • Commits signed with any key derivable from the current root mnemonic → ✅ verified
  • Commits signed with a key from a mnemonic that is gone (e.g. fresh keygen with --destroy-mnemonic) → ⚠️ unverifiable (key not available), not ❌ INVALID
  • Commits where the key is present but the signature bytes don't match → ❌ INVALID (tampered)

Acceptance criteria

  1. Running muse verify on a repo with commits from a rotated-but-still-derivable key returns ✅ for those commits (HD sweep finds the right key).
  2. Commits from a destroyed/unavailable key show a distinct warning level, not the same INVALID message used for genuine signature mismatches.
  3. Genuine tampered commits (bytes modified post-sign) still show ❌ INVALID.
  4. muse verify --strict flag (or equivalent) can be used to treat unverifiable-key commits as failures for CI/compliance contexts.

Out of scope

  • Re-signing old commits with the new key (would change commit IDs)
  • Storing retired public keys in the identity repo (future hardening)
File History 5 commits
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 8 days ago
sha256:408916fc5973ba59c6e4eebaa80ebdcc801c0a63205651e25009d11548f79454 chore: bump version to 0.2.0.dev2 — nightly.2, matching muse Sonnet 4.6 patch 11 days ago
sha256:d035733f21ccff27735fddebfbbe0ed24565a32a22db8de5885402262671ecd2 chore: bump version to 0.2.0rc15 for musehub#113 fix release Sonnet 4.6 patch 14 days ago
sha256:0032d6cfa33bc3c8367436ad768e7dd0e339b4332153160247da8266cb5fa352 Merge branch 'task/version-tags-phase3-server' into dev Human 17 days ago