gabriel / musehub public
verify-old-key-signatures.md markdown
58 lines 2.8 KB
Raw
sha256:42bc547653458bb15e283222247af0237872d9cb5c2a72ad2ca1c111ed2c0ca4 feat(9A-4 F7): overseer-run provenance enrichment API for S… Human minor ⚠ breaking 13 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 1 commit
sha256:e5530c6b8996b96fc4030d6d30fe4f688926bdda2875fb01d303092b11513bd2 fix(9A-4 F7): env alias + staging secrets for overseer prov… Human minor 10 days ago