57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
"""Lightweight governance ledger scaffold with crypto-like signing.
|
|
|
|
This module uses a simple RSA key pair to sign audit entries for tamper-evident
|
|
log entries. It is intentionally minimal but provides a realistic API for MVP.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any, Dict, List
|
|
from dataclasses import dataclass, asdict
|
|
|
|
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
|
|
|
|
@dataclass
|
|
class AuditEntry:
|
|
payload: Dict[str, Any]
|
|
signature: str
|
|
signer: str
|
|
|
|
|
|
class GovernanceLedger:
|
|
def __init__(self, signer_id: str = "governor") -> None:
|
|
self.signer_id = signer_id
|
|
self._private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
|
self._public_key = self._private_key.public_key()
|
|
self.entries: List[AuditEntry] = []
|
|
|
|
def sign(self, payload: Dict[str, Any]) -> AuditEntry:
|
|
payload_bytes = json.dumps(payload, sort_keys=True).encode("utf-8")
|
|
signature = self._private_key.sign(
|
|
payload_bytes,
|
|
padding.PSS(
|
|
mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH
|
|
),
|
|
hashes.SHA256(),
|
|
)
|
|
entry = AuditEntry(payload=payload, signature=signature.hex(), signer=self.signer_id)
|
|
self.entries.append(entry)
|
|
return entry
|
|
|
|
def verify(self, entry: AuditEntry) -> bool:
|
|
payload_bytes = json.dumps(entry.payload, sort_keys=True).encode("utf-8")
|
|
try:
|
|
self._public_key.verify(
|
|
bytes.fromhex(entry.signature),
|
|
payload_bytes,
|
|
padding.PSS(
|
|
mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH
|
|
),
|
|
hashes.SHA256(),
|
|
)
|
|
return True
|
|
except Exception:
|
|
return False
|