Verify in Python
Verify the Ed25519 signature of an acf-mcp output in Python with the cryptography library (PyPI). Compatible with a Python audit pipeline or an Airflow job.
iNote
One dependency:
pip install cryptography. No network call. Verification is constant-time thanks to the libsodium implementation behind cryptography.Installation
bash
pip install 'cryptography>=42'Complete snippet
verify_doctrine.pypython
import base64
import json
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.hazmat.primitives.serialization import load_der_public_key
from cryptography.exceptions import InvalidSignature
PUBLIC_KEY_SPKI_B64 = (
"MCowBQYDK2VwAyEAojtKfh20SGGV63LMETjZBXRWo2tY0viAYziG/y3/L0s="
)
# 1. Decode the SPKI-encoded public key.
spki = base64.b64decode(PUBLIC_KEY_SPKI_B64)
public_key = load_der_public_key(spki)
assert isinstance(public_key, Ed25519PublicKey), (
"Unexpected key type — acf-mcp uses Ed25519"
)
# 2. Load the signed tool output.
with open("tool-output.json", "r", encoding="utf-8") as f:
signed = json.load(f)
# 3. The signed message is the doctrine_hash field as UTF-8.
message = signed["doctrine_hash"].encode("utf-8")
# 4. Strip "ed25519:" prefix, decode signature from base64.
sig_b64 = signed["doctrine_signature"].removeprefix("ed25519:")
signature = base64.b64decode(sig_b64)
# 5. Verify.
try:
public_key.verify(signature, message)
print("✓ signature valid")
except InvalidSignature:
print("✗ signature INVALID")
CI integration
To verify every archived output in a CI job: wrap this script as verify(path: str) -> bool and call it on every file under ./audit-trail/*.json. The signature is deterministic, so a regression test pinned on doctrine_hash immediately catches any silent mutation.
Failure modes
InvalidSignature— the content was tampered with OR the wrong public key is in use.UnsupportedAlgorithm— cryptography < 2.6. Upgrade.ValueErrorsur base64 — signature lost characters on copy-paste (missing = padding).