fix: cryptographically bind DGR-001 evidence

This commit is contained in:
Dobromir Popov
2026-07-13 19:38:14 +03:00
parent 9e67b829e3
commit b1c9deeb01
11 changed files with 1349 additions and 903 deletions

View File

@@ -25,16 +25,23 @@ the release gate is allowed to reach.
from __future__ import annotations
import base64
import binascii
import hashlib
import json
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any, Mapping
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from .recipe_benchmark import Lane, REPORT_SCHEMA_VERSION
# Layout of the contract document understood by this reader.
CONTRACT_SCHEMA_VERSION = 1
PROVENANCE_SCHEMA_VERSION = 1
REAL_REPORT_PRODUCER = "meshnet_node.recipe_drivers.run_configured_benchmark/v1"
VERDICT_PROMOTE = "promote"
VERDICT_OPTIMIZE = "optimize"
@@ -146,6 +153,66 @@ def _canonical_sha256(value: Any) -> str:
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
def report_signing_payload(report: Mapping[str, Any]) -> bytes:
"""Canonical report bytes covered by the Ed25519 signature."""
provenance = report.get("provenance")
if not isinstance(provenance, Mapping):
raise PerformanceContractError("real benchmark report lacks signed provenance")
unsigned = dict(report)
unsigned_provenance = dict(provenance)
unsigned_provenance.pop("signature", None)
unsigned["provenance"] = unsigned_provenance
return json.dumps(
unsigned, sort_keys=True, separators=(",", ":"), ensure_ascii=False
).encode("utf-8")
def _decode_base64(value: Any, label: str) -> bytes:
if not isinstance(value, str):
raise PerformanceContractError(f"report lacks {label}")
try:
return base64.b64decode(value, validate=True)
except (binascii.Error, ValueError) as exc:
raise PerformanceContractError(f"report carries invalid {label}") from exc
def _verify_real_provenance(
contract: PerformanceContract, report: Mapping[str, Any]
) -> None:
provenance = report.get("provenance")
if not isinstance(provenance, Mapping):
raise PerformanceContractError("real benchmark report lacks signed provenance")
if provenance.get("schema_version") != PROVENANCE_SCHEMA_VERSION:
raise PerformanceContractError("report provenance schema is unsupported")
if provenance.get("producer") != REAL_REPORT_PRODUCER:
raise PerformanceContractError("report was not emitted by the canonical real runner")
if provenance.get("signature_algorithm") != "ed25519":
raise PerformanceContractError("report provenance is not Ed25519 signed")
for field in ("run_id", "started_at", "completed_at"):
if not provenance.get(field):
raise PerformanceContractError(f"report provenance lacks {field}")
required_config = contract.baseline.get("required_config_sha256")
if not required_config or provenance.get("config_sha256") != required_config:
raise PerformanceContractError("report config digest does not match the locked config")
encoded_public_key = contract.baseline.get("required_signer_public_key")
public_key_bytes = _decode_base64(encoded_public_key, "locked signer public key")
if len(public_key_bytes) != 32:
raise PerformanceContractError("locked Ed25519 public key must be 32 bytes")
expected_fingerprint = hashlib.sha256(public_key_bytes).hexdigest()
if provenance.get("signer_public_key_sha256") != expected_fingerprint:
raise PerformanceContractError("report signer fingerprint does not match the contract")
signature = _decode_base64(provenance.get("signature"), "Ed25519 signature")
try:
Ed25519PublicKey.from_public_bytes(public_key_bytes).verify(
signature, report_signing_payload(report)
)
except (InvalidSignature, ValueError) as exc:
raise PerformanceContractError("report Ed25519 signature verification failed") from exc
def _validate_report(contract: PerformanceContract, report: Mapping[str, Any]) -> None:
"""Fail closed when a report is not the experiment the contract locked."""
try:
@@ -187,6 +254,8 @@ def _validate_report(contract: PerformanceContract, report: Mapping[str, Any]) -
raise PerformanceContractError(
f"report evidence class {evidence_class!r} does not satisfy {required_evidence!r}"
)
if evidence_class in {"local-real", "multi-machine-real"}:
_verify_real_provenance(contract, report)
if required_evidence and (
not isinstance(host, Mapping)
or any(key not in host for key in ("hostname", "platform", "python", "cpu_count"))
@@ -221,8 +290,18 @@ def _validate_report(contract: PerformanceContract, report: Mapping[str, Any]) -
model_id = plan.get("model_id")
model_revision = plan.get("model_revision")
required_device = contract.baseline.get("required_device")
required_artifacts = dict(contract.baseline.get("required_artifact_sha256") or {})
required_runtimes = dict(contract.baseline.get("required_recipe_runtime") or {})
required_backends = dict(contract.baseline.get("required_backend_detail") or {})
required_host = dict(contract.baseline.get("required_host_identity") or {})
for field, expected in required_host.items():
if host.get(field) != expected:
raise PerformanceContractError(
f"report host/runtime field {field!r} does not match the locked identity"
)
for entry in recipes:
recipe = entry.get("recipe", {})
recipe_id = recipe.get("id")
if required_device and recipe.get("device") != required_device:
raise PerformanceContractError(
f"recipe {recipe.get('id')!r} did not run on locked device {required_device!r}"
@@ -235,6 +314,30 @@ def _validate_report(contract: PerformanceContract, report: Mapping[str, Any]) -
digest = recipe.get("artifact_sha256", "")
if not isinstance(digest, str) or len(digest) != 64:
raise PerformanceContractError("report lacks an artifact SHA-256 digest")
expected_digest = required_artifacts.get(recipe_id)
if not expected_digest or digest != expected_digest:
raise PerformanceContractError(
f"recipe {recipe_id!r} artifact digest does not match the contract"
)
expected_runtime = required_runtimes.get(recipe_id)
if not isinstance(expected_runtime, Mapping):
raise PerformanceContractError(
f"contract lacks runtime identity for recipe {recipe_id!r}"
)
actual_runtime = {
field: recipe.get(field) for field in expected_runtime
}
if actual_runtime != dict(expected_runtime):
raise PerformanceContractError(
f"recipe {recipe_id!r} runtime identity does not match the contract"
)
if entry.get("available"):
expected_backend = required_backends.get(recipe_id)
actual_backend = entry.get("load", {}).get("backend_detail")
if not expected_backend or actual_backend != expected_backend:
raise PerformanceContractError(
f"recipe {recipe_id!r} backend identity does not match the contract"
)
if entry.get("available"):
cells = entry.get("concurrency", {})
missing_cells = required_levels - {int(level) for level in cells}
@@ -666,6 +769,23 @@ def baseline_from_report(report: Mapping[str, Any]) -> dict[str, Any]:
"plan_sha256": _canonical_sha256(report["plan"]),
"reference_recipe_id": report["reference_recipe_id"],
"host": report["host"],
"provenance": dict(report.get("provenance") or {}),
"artifact_sha256": {
recipe_id: entry["recipe"]["artifact_sha256"]
for recipe_id, entry in entries.items()
},
"recipe_runtime": {
recipe_id: {
field: entry["recipe"].get(field)
for field in ("runtime", "weight_format", "weight_quantization", "device")
}
for recipe_id, entry in entries.items()
},
"backend_detail": {
recipe_id: entry.get("load", {}).get("backend_detail")
for recipe_id, entry in entries.items()
if entry.get("available")
},
"recipes": {},
}
for recipe_id, entry in entries.items():

View File

@@ -35,7 +35,7 @@ from dataclasses import asdict, dataclass, field
from difflib import SequenceMatcher
from enum import Enum
from pathlib import Path
from typing import Any, Protocol, Sequence
from typing import Any, Mapping, Protocol, Sequence
# Layout of the report document produced by :func:`build_report`.
REPORT_SCHEMA_VERSION = 1
@@ -581,6 +581,7 @@ def build_report(
*,
host: dict[str, Any],
evidence_class: str,
provenance: Mapping[str, Any] | None = None,
) -> dict:
"""Assemble the machine-readable benchmark document.
@@ -590,6 +591,8 @@ def build_report(
"""
if evidence_class not in {"synthetic", "local-real", "multi-machine-real"}:
raise BenchmarkError(f"unknown evidence class {evidence_class!r}")
if evidence_class != "synthetic" and not isinstance(provenance, Mapping):
raise BenchmarkError("non-synthetic reports require canonical signed provenance")
references = [m for m in measurements if m.recipe.is_reference]
if len(references) != 1:
@@ -605,7 +608,7 @@ def build_report(
for measurement in measurements
if measurement is not reference and measurement.available
]
return {
report = {
"schema_version": REPORT_SCHEMA_VERSION,
"evidence_class": evidence_class,
"plan": plan.to_dict(),
@@ -614,6 +617,9 @@ def build_report(
"recipes": [measurement.to_dict() for measurement in measurements],
"drift": drift,
}
if provenance is not None:
report["provenance"] = dict(provenance)
return report
def format_summary(report: dict) -> str:

View File

@@ -20,6 +20,7 @@ rules:
from __future__ import annotations
import base64
import hashlib
import hmac
import json
@@ -27,15 +28,27 @@ import os
import platform
import re
import socket
import stat
import subprocess
import sys
import tempfile
import time
import urllib.error
import urllib.request
import uuid
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Mapping
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from .performance_contract import (
PROVENANCE_SCHEMA_VERSION,
REAL_REPORT_PRODUCER,
_canonical_sha256,
report_signing_payload,
)
from .recipe_benchmark import (
BenchmarkError,
BenchmarkPlan,
@@ -50,6 +63,7 @@ from .recipe_benchmark import (
)
REAL_INFERENCE_ENV = "MESHNET_ENABLE_REAL_INFERENCE_TESTS"
EVIDENCE_SIGNING_KEY_ENV = "MESHNET_EVIDENCE_SIGNING_KEY"
def real_inference_enabled() -> bool:
@@ -64,6 +78,37 @@ def require_real_inference() -> None:
)
def _load_evidence_signing_key() -> Ed25519PrivateKey:
raw_path = os.environ.get(EVIDENCE_SIGNING_KEY_ENV)
if not raw_path:
raise BenchmarkError(
f"real evidence requires {EVIDENCE_SIGNING_KEY_ENV} to name an Ed25519 private key"
)
path = Path(raw_path).expanduser().resolve(strict=True)
if os.name != "nt" and stat.S_IMODE(path.stat().st_mode) != 0o600:
raise BenchmarkError("evidence signing key must have mode 0600")
key = serialization.load_pem_private_key(path.read_bytes(), password=None)
if not isinstance(key, Ed25519PrivateKey):
raise BenchmarkError("evidence signing key must be Ed25519")
return key
def _utc_now() -> str:
return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
def _sign_report(report: dict[str, Any], key: Ed25519PrivateKey) -> None:
public_key = key.public_key().public_bytes(
serialization.Encoding.Raw, serialization.PublicFormat.Raw
)
report["provenance"]["signer_public_key_sha256"] = hashlib.sha256(
public_key
).hexdigest()
report["provenance"]["signature"] = base64.b64encode(
key.sign(report_signing_payload(report))
).decode("ascii")
def _process_rss(pid: int | None = None) -> int:
"""Resident bytes for a process and its children, or 0 when unobservable."""
try:
@@ -120,7 +165,7 @@ def _artifact_sha256(path: Path) -> str:
return digest.hexdigest()
def _host_manifest() -> dict[str, Any]:
def _host_manifest(config: Mapping[str, Any] | None = None) -> dict[str, Any]:
"""Capture non-secret host facts with the report rather than trusting prose."""
manifest: dict[str, Any] = {
"hostname": socket.gethostname(),
@@ -142,6 +187,30 @@ def _host_manifest() -> dict[str, Any]:
)
except ImportError:
manifest["torch_version"] = None
llama_identities: dict[str, dict[str, str]] = {}
for spec in (config or {}).get("recipes", ()):
driver = spec.get("driver", {})
if driver.get("type") != "llama-cpp-server":
continue
binary = Path(driver["binary"]).resolve(strict=True)
key = str(binary)
if key in llama_identities:
continue
version_result = subprocess.run(
[str(binary), "--version"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
timeout=10,
)
llama_identities[key] = {
"sha256": _artifact_sha256(binary),
"version": " | ".join(version_result.stdout.strip().splitlines()),
}
if llama_identities:
manifest["llama_server_identities"] = llama_identities
return manifest
@@ -635,6 +704,13 @@ def run_configured_benchmark(config: Mapping[str, Any]) -> dict:
"""
require_real_inference()
_validate_config(config)
evidence_class = config.get("evidence_class", "local-real")
if evidence_class not in {"local-real", "multi-machine-real"}:
raise BenchmarkError("canonical real runner cannot emit synthetic evidence")
signing_key = _load_evidence_signing_key()
started_at = _utc_now()
run_id = str(uuid.uuid4())
config_sha256 = _canonical_sha256(config)
plan = _plan_from_config(config)
from .recipe_benchmark import RecipeMeasurement # local import keeps the seam obvious
@@ -656,9 +732,20 @@ def run_configured_benchmark(config: Mapping[str, Any]) -> dict:
if driver is not None:
driver.close()
return build_report(
report = build_report(
plan,
measurements,
host={**dict(config.get("host", {})), **_host_manifest()},
evidence_class=config.get("evidence_class", "local-real"),
host={**dict(config.get("host", {})), **_host_manifest(config)},
evidence_class=evidence_class,
provenance={
"schema_version": PROVENANCE_SCHEMA_VERSION,
"producer": REAL_REPORT_PRODUCER,
"run_id": run_id,
"started_at": started_at,
"completed_at": _utc_now(),
"config_sha256": config_sha256,
"signature_algorithm": "ed25519",
},
)
_sign_report(report, signing_key)
return report