secure-messaging/scripts/sign_config.py
George Lambert 9eed0b1942
Some checks are pending
ci / python (push) Waiting to run
ci / go (push) Waiting to run
S14: NPE fail-closed adapter; npe mode never falls back to lab-xor
2026-09-15 22:22:56 -04:00

59 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Generate a lab Ed25519 key and a signed secure-messaging.json.
Usage:
python3 scripts/sign_config.py --out examples/secure-messaging.signed.json
Private key is written to keys/config.ed25519.pem (gitignored).
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "python"))
from secure_messaging.admin_history import AdminHistory
from secure_messaging.signed_config import generate_signing_key, pem_private, pem_public, save_signed, sign
DEFAULT_PAYLOAD = {
"crypto": {"mode": "lab-xor", "system_key_id": "lab-system"},
"routing": {"mode": "passthrough"},
"admin": {"history_cube": "admin-history"},
"logging": {"mode": "summary"},
}
def main() -> None:
p = argparse.ArgumentParser()
p.add_argument("--out", default=str(ROOT / "examples" / "secure-messaging.signed.json"))
p.add_argument("--actor", default="lab-admin")
args = p.parse_args()
keydir = ROOT / "keys"
keydir.mkdir(mode=0o700, exist_ok=True)
priv_path = keydir / "config.ed25519.pem"
if priv_path.exists():
from cryptography.hazmat.primitives.serialization import load_pem_private_key
priv = load_pem_private_key(priv_path.read_bytes(), password=None)
else:
priv = generate_signing_key()
priv_path.write_bytes(pem_private(priv))
priv_path.chmod(0o600)
(keydir / "config.ed25519.pub.pem").write_bytes(pem_public(priv.public_key()))
out = Path(args.out)
prev = out.read_text() if out.exists() else ""
signed = sign(DEFAULT_PAYLOAD, priv)
out.parent.mkdir(parents=True, exist_ok=True)
save_signed(out, signed)
hist = AdminHistory(ROOT / "examples" / "admin-history")
hist.append_change(actor=args.actor, prev_text=prev, new_text=signed.dumps())
print("wrote", out)
print("history", hist.path)
if __name__ == "__main__":
main()