# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-identity-continuity-invariants-must-survive-a-hardware-security-module-failover.md # Remnant Warrant: https://corpusfetch.com/c/what-identity-continuity-invariants-must-survive-a-hardware-security-module-failover.warrant.json # Markdown SHA-256: 9963b19246b1fd0dcdc108a89fedfb021f59d9a6728e0b24803fc0e117a8dee1 # Code AST SHA-256: 1dca4d2e4033fa2b959ed667b197fbd81bef0df9abaf2be8244eaeb79b1e2c0a # Verified Classes: HSFVerdict, HSMState, HSMPolicy, HSMManifest, HSMFailoverGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class HSFVerdict(Enum): NO_FAILOVER = auto() CONTINUITY_VERIFIED = auto() KEY_REISSUED = auto() UNVERIFIED_FAILOVER = auto() @dataclass(frozen=True) class HSMState: failover_occurred: bool continuity_proof: str | None pre_failover_key_fingerprint: str post_failover_key_fingerprint: str failover_epoch: float | None @dataclass(frozen=True) class HSMPolicy: require_continuity_proof: bool @dataclass(frozen=True) class HSMManifest: verdict: HSFVerdict directive: str manifest_digest: str class HSMFailoverGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_failover( cls, state: HSMState, policy: HSMPolicy ) -> HSMManifest: # Gate 1: No failover if not state.failover_occurred: digest = cls._hash(json.dumps({ "key": state.pre_failover_key_fingerprint, "status": "NO_FAILOVER" }, sort_keys=True)) return HSMManifest( verdict=HSFVerdict.NO_FAILOVER, directive="PROCEED: No HSM failover occurred.", manifest_digest=digest ) # Gate 2: Key material match if state.pre_failover_key_fingerprint != state.post_failover_key_fingerprint: return HSMManifest( verdict=HSFVerdict.KEY_REISSUED, directive=f"HALT: Key material changed: {state.pre_failover_key_fingerprint} -> {state.post_failover_key_fingerprint}. Re-registration required.", manifest_digest=cls._hash(f"REISSUED:{state.post_failover_key_fingerprint}") ) # Gate 3: Continuity proof if policy.require_continuity_proof and not state.continuity_proof: return HSMManifest( verdict=HSFVerdict.UNVERIFIED_FAILOVER, directive="HALT: Failover occurred but no continuity proof. Downstream verification may fail.", manifest_digest=cls._hash(f"NO_PROOF:{state.failover_epoch:.0f}") ) # Gate 4: Verified digest = cls._hash(json.dumps({ "key": state.post_failover_key_fingerprint, "proof": state.continuity_proof or "NONE", "epoch": f"{state.failover_epoch:.0f}" if state.failover_epoch else "N/A" }, sort_keys=True)) return HSMManifest( verdict=HSFVerdict.CONTINUITY_VERIFIED, directive=f"PROCEED: HSM failover verified, key continuous.", manifest_digest=digest )