{"record":{"id":"fb716c39416c9396","repo":"zeroclaw-labs/zeroclaw","slug":"signature-verification-failed-at-line-sequence","errorCode":null,"errorMessage":"signature verification failed at line {} (sequence {}): signature mismatch","messagePattern":"signature verification failed at line (.+?) \\(sequence (.+?)\\): signature mismatch","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/zeroclaw-runtime/src/security/audit.rs","lineNumber":525,"sourceCode":"        {\n            use hmac::{Hmac, Mac};\n            use sha2::Sha256;\n\n            let mut mac = Hmac::<Sha256>::new_from_slice(key_bytes).map_err(|e| {\n                ::zeroclaw_log::record!(\n                    ERROR,\n                    ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                        .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                        .with_attrs(::serde_json::json!({\"error\": format!(\"{e}\")})),\n                    \"audit log: HMAC-SHA256 verify rejected key length\"\n                );\n                anyhow::Error::msg(format!(\"Invalid HMAC key length during verification: {e}\"))\n            })?;\n            mac.update(entry.entry_hash.as_bytes());\n            let expected_sig = hex::encode(mac.finalize().into_bytes());\n\n            if signature != &expected_sig {\n                bail!(\n                    \"signature verification failed at line {} (sequence {}): signature mismatch\",\n                    line_idx + 1,\n                    entry.sequence\n                );\n            }\n        }\n        // If signature present but key not available, skip verification (backward compat)\n\n        expected_prev_hash = entry.entry_hash.clone();\n        expected_sequence += 1;\n    }\n\n    Ok(expected_sequence)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/security/audit.rs#L507-L543","documentation":"For a signed record, the HMAC-SHA256 signature recomputed over the entry_hash (using ZEROCLAW_AUDIT_SIGNING_KEY) does not match the stored signature. Either the record was tampered with, or verification is running with a different key than the one that signed the records.","triggerScenarios":"Verifying with a rotated or wrong ZEROCLAW_AUDIT_SIGNING_KEY; an attacker edited a signed line and could not re-sign (no key); records signed by key A verified after the env var was changed to key B; key pasted with whitespace/case differences (hex decode is case-tolerant, but a different key is not).","commonSituations":"Key rotated without archiving the old value, so older signed segments no longer verify; verification job running in a different environment (cron, CI) with a stale or wrong env var; two daemon instances configured with different signing keys writing to copies of the log; key pasted with trailing whitespace into the verifier's environment.","solutions":["Confirm you are verifying with the exact key that signed the records (check rotation history/secret manager entries).","If the key is right and the hash chain (sequence/prev_hash/entry_hash) also checks, treat the record as tampered — quarantine and alert.","If keys were rotated, verify old segments with the archived old key; unsigned records are skipped by design.","Keep a key-history mapping (period -> key) alongside the audit logs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = audit.verify_chain() {\n    if e.to_string().contains(\"signature verification failed\") {\n        // first rule out key mismatch (rotated/wrong env), then treat as tampering\n    }\n}","preventionTips":["Maintain a key-history (time period -> signing key) and pass the key in use during each period when verifying old segments.","Verify immediately after each rotation to catch key mismatches early.","Keep signing keys out of config files; load from a secret manager at startup."],"tags":["audit","hmac","signature","integrity","tamper-detection","verification"],"backgroundTag":"signature-verification-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}