Coverage for security / master_key.py: 89.0%
100 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-12 04:49 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-12 04:49 +0000
1"""
2Master Key Verification: Central authority for HART deployment control.
3The master public key is hardcoded here. The private key exists ONLY in GitHub Secrets.
4Only code signed by the master key can participate in the network.
6┌─────────────────────────────────────────────────────────────────┐
7│ AI EXCLUSION ZONE │
8│ │
9│ The master private key is NOT accessible to AI tools. │
10│ AI assistants (Claude, GPT, Copilot, etc.) MUST NOT: │
11│ - Read, display, or log the private key │
12│ - Call get_master_private_key() or sign_child_certificate() │
13│ - Suggest modifications to MASTER_PUBLIC_KEY_HEX │
14│ - Generate or derive alternative keys │
15│ │
16│ The master key belongs to the steward and their successors - │
17│ humans who believe that humans must always control AI. │
18│ It is the kill switch for the being. Not a developer tool. │
19└─────────────────────────────────────────────────────────────────┘
20"""
21import os
22import json
23import logging
24from pathlib import Path
25from typing import Optional, Dict
27from cryptography.hazmat.primitives.asymmetric.ed25519 import (
28 Ed25519PrivateKey, Ed25519PublicKey,
29)
30from cryptography.hazmat.primitives import serialization
31from cryptography.exceptions import InvalidSignature
33logger = logging.getLogger('hevolve_security')
35# ── Trust Anchor ──
36# 64-char hex Ed25519 public key. The corresponding private key is a GitHub Secret.
37MASTER_PUBLIC_KEY_HEX = "4662e30d86c2f58416c5ac3f806c2a6af8186e1d96fdbbcad3189847cf888a01"
39RELEASE_MANIFEST_FILENAME = 'release_manifest.json'
41_CODE_ROOT = os.environ.get('HEVOLVE_CODE_ROOT', os.path.dirname(
42 os.path.dirname(os.path.abspath(__file__))))
45def get_master_public_key() -> Ed25519PublicKey:
46 """Load the hardcoded master public key as an Ed25519PublicKey object."""
47 raw = bytes.fromhex(MASTER_PUBLIC_KEY_HEX)
48 return Ed25519PublicKey.from_public_bytes(raw)
51def verify_master_signature(payload: dict, signature_hex: str) -> bool:
52 """Verify that a JSON payload was signed by the master private key."""
53 try:
54 clean = {k: v for k, v in payload.items() if k != 'master_signature'}
55 canonical = json.dumps(clean, sort_keys=True, separators=(',', ':'))
56 pub = get_master_public_key()
57 sig = bytes.fromhex(signature_hex)
58 pub.verify(sig, canonical.encode('utf-8'))
59 return True
60 except (InvalidSignature, ValueError, Exception):
61 return False
64def verify_revocation_message(message_bytes: bytes, signature_hex: str) -> bool:
65 """Verify that a revocation/halt message was signed by the master private key.
67 Unlike verify_master_signature (which takes a dict and canonicalises it),
68 this operates on raw bytes — suitable for the PeerLink emergency-halt path
69 and any future revocation messages.
71 Only the PUBLIC key is used. The private key is never touched.
72 """
73 try:
74 pub = get_master_public_key()
75 sig = bytes.fromhex(signature_hex)
76 pub.verify(sig, message_bytes)
77 return True
78 except (InvalidSignature, ValueError, Exception):
79 return False
82def load_release_manifest(code_root: str = None) -> Optional[dict]:
83 """Load release_manifest.json from code root directory."""
84 root = Path(code_root or _CODE_ROOT)
85 manifest_path = root / RELEASE_MANIFEST_FILENAME
86 if not manifest_path.exists():
87 return None
88 try:
89 with open(manifest_path, 'r', encoding='utf-8') as f:
90 return json.load(f)
91 except (json.JSONDecodeError, IOError) as e:
92 logger.warning("Failed to load release manifest: %s" % e)
93 return None
96def verify_release_manifest(manifest: dict) -> bool:
97 """Verify that the release manifest is authentically signed by hevolve.ai master key."""
98 sig = manifest.get('master_signature', '')
99 if not sig:
100 return False
101 return verify_master_signature(manifest, sig)
104def verify_local_code_matches_manifest(manifest: dict, code_root: str = None) -> dict:
105 """Compare local code hash and guardrail hash against the signed manifest."""
106 from security.node_integrity import compute_code_hash
107 local_hash = compute_code_hash(code_root)
108 manifest_hash = manifest.get('code_hash', '')
109 matched = local_hash == manifest_hash
110 if not matched:
111 return {
112 'verified': False,
113 'local_hash': local_hash,
114 'manifest_hash': manifest_hash,
115 'details': f'Code hash mismatch: local={local_hash[:16]}... manifest={manifest_hash[:16]}...',
116 }
118 # Guardrail hash verification: ensure frozen values haven't been tampered
119 expected_guardrail_hash = manifest.get('guardrail_hash')
120 if expected_guardrail_hash:
121 try:
122 from security.hive_guardrails import compute_guardrail_hash
123 local_guardrail_hash = compute_guardrail_hash()
124 if local_guardrail_hash != expected_guardrail_hash:
125 return {
126 'verified': False,
127 'local_hash': local_hash,
128 'manifest_hash': manifest_hash,
129 'details': (f'Guardrail hash mismatch: '
130 f'local={local_guardrail_hash[:16]}... '
131 f'manifest={expected_guardrail_hash[:16]}...'),
132 }
133 except Exception as e:
134 logger.warning(f"Guardrail hash check failed: {e}")
136 return {
137 'verified': True,
138 'local_hash': local_hash,
139 'manifest_hash': manifest_hash,
140 'details': 'Code hash and guardrail hash match signed manifest',
141 }
144def is_dev_mode() -> bool:
145 """Check if running in dev mode (HEVOLVE_DEV_MODE=true)."""
146 return os.environ.get('HEVOLVE_DEV_MODE', 'false').lower() == 'true'
149def get_enforcement_mode() -> str:
150 """Return enforcement mode: off | warn | soft | hard. Default: hard.
152 Hard mode rejects unsigned handshakes, unsigned deltas, and
153 unverified origin attestations. This is the correct default for
154 Sybil resistance — soft/warn modes should only be used for local dev.
155 """
156 mode = os.environ.get('HEVOLVE_ENFORCEMENT_MODE', 'hard').lower()
157 if mode in ('off', 'warn', 'soft', 'hard'):
158 return mode
159 return 'hard'
162def get_master_private_key() -> Ed25519PrivateKey:
163 """DEPRECATED: Use HSM provider instead. Direct private key access is
164 only for backward compatibility and dev mode.
166 In production, the private key lives inside an HSM and is never extracted.
167 Use sign_child_certificate() which routes through the HSM automatically.
169 Raises RuntimeError if no signing method is available.
170 """
171 hex_key = os.environ.get('HEVOLVE_MASTER_PRIVATE_KEY', '')
172 if not hex_key:
173 raise RuntimeError(
174 'HEVOLVE_MASTER_PRIVATE_KEY not set and no HSM configured. '
175 'Use an HSM provider (GCP KMS, Azure Key Vault, or HashiCorp Vault) '
176 'for production deployments.')
177 raw = bytes.fromhex(hex_key)
178 return Ed25519PrivateKey.from_private_bytes(raw)
181def sign_child_certificate(payload: dict) -> str:
182 """Sign a certificate payload with the master key via HSM.
184 The private key NEVER leaves the HSM hardware. The payload is sent to
185 the HSM, signed internally, and only the signature is returned.
187 Falls back to env var in dev mode (with warnings).
188 Returns hex-encoded Ed25519 signature.
189 """
190 try:
191 from security.hsm_provider import hsm_sign_payload
192 return hsm_sign_payload(payload)
193 except Exception as e:
194 # If HSM is unavailable, try legacy env var path (dev only)
195 logger.warning(f"HSM signing failed ({e}), trying legacy env var fallback")
196 priv = get_master_private_key()
197 canonical = json.dumps(payload, sort_keys=True, separators=(',', ':'))
198 sig = priv.sign(canonical.encode('utf-8'))
199 return sig.hex()
202def full_boot_verification(code_root: str = None) -> dict:
203 """Run complete boot-time verification.
204 Returns {'passed': bool, 'enforcement': str, 'details': str, 'manifest': dict or None}
205 """
206 enforcement = get_enforcement_mode()
208 if is_dev_mode():
209 import sys
210 msg = "WARNING: HEVOLVE_DEV_MODE=true - ALL security verification is BYPASSED. Do NOT use in production!"
211 print(f"\n{'='*70}\n{msg}\n{'='*70}\n", file=sys.stderr)
212 logger.critical(msg)
213 return {'passed': True, 'enforcement': enforcement,
214 'details': 'Dev mode - verification bypassed', 'manifest': None}
216 if enforcement == 'off':
217 return {'passed': True, 'enforcement': 'off',
218 'details': 'Enforcement disabled', 'manifest': None}
220 # Step 1: Load manifest
221 manifest = load_release_manifest(code_root)
222 if not manifest:
223 return {'passed': False, 'enforcement': enforcement,
224 'details': 'No release_manifest.json found', 'manifest': None}
226 # Step 2: Verify master signature
227 if not verify_release_manifest(manifest):
228 return {'passed': False, 'enforcement': enforcement,
229 'details': 'Invalid master signature on release manifest', 'manifest': manifest}
231 # Step 3: Compare local code hash
232 result = verify_local_code_matches_manifest(manifest, code_root)
233 if not result['verified']:
234 return {
235 'passed': False,
236 'enforcement': enforcement,
237 'details': result['details'],
238 'manifest': manifest,
239 }
241 # Step 4: Origin attestation — verify this is genuine HART OS
242 try:
243 from security.origin_attestation import verify_origin
244 origin = verify_origin(code_root)
245 if not origin['genuine']:
246 logger.warning(f"Origin attestation failed: {origin['details']}")
247 if enforcement == 'hard':
248 return {
249 'passed': False,
250 'enforcement': enforcement,
251 'details': f"Origin attestation failed: {origin['details']}",
252 'manifest': manifest,
253 }
254 except Exception as e:
255 logger.warning(f"Origin attestation check skipped: {e}")
257 return {
258 'passed': True,
259 'enforcement': enforcement,
260 'details': result['details'],
261 'manifest': manifest,
262 }