Verify the master key against the database at startup (B-89, SEC-49, SEC-50, SEC-09)

The lifespan decrypts the key and compares a fixed sample (reserve/round pool
addresses, the 10 lowest and highest user addresses, unrevealed round secrets)
with the database, and refuses to serve on any mismatch without printing key
material. The key scripts refuse a new or imported key that would not reproduce
the stored addresses, and write 0600.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5.5 committed 2026-10-18 00:38:26 +02:00
1 parent 32df50cb75
commit 55d852fe08
14 files changed
+281 -46

No files matched your search

+2
View File
@@ -32,6 +32,7 @@ from app.tx.broadcast import RbfBumper
from app.tx.confirmation import ConfirmationPoller
from app.tx.locks import UserLocks
from app.tx.reconcile import PendingTransactionReconciler
from app.wallet.verify import verify_master_key
logger = logging.getLogger(__name__)
@@ -53,6 +54,7 @@ async def lifespan(app: FastAPI):
settings.electrum_cert_pin,
)
validate_quorum_servers(endpoints) # B-84: refuses to serve without a usable quorum
verify_master_key() # B-89: refuses to serve with a key that did not produce the stored addresses
logger.info("Electrum endpoints (in rotation order): %s", ", ".join(str(e) for e in endpoints))
listener = ElectrumListener(