Verify an attestation
Every endpoint carries a signed statement of exactly what it serves: the Civitai model and version it came from, the SHA-256 published there, the SHA-256 we measured on the bytes we fetched, the compiled artifact hash, and the verified owner identity. For composed endpoints the statement includes the ordered component list with scales — the full stack, as served.
The point: you don't have to trust our API. Fetch the signing key once, then verify any statement offline, forever.
The key
curl -s https://epm-router.uridemay.workers.dev/.well-known/epm-attestation
{
"algorithm": "ed25519",
"public_key": "…hex…",
"canonicalization": "JSON, sorted keys, compact separators, UTF-8"
}
Verify offline
import json
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
def verify(public_key_hex: str, statement: dict, signature_hex: str) -> bool:
key = Ed25519PublicKey.from_public_bytes(bytes.fromhex(public_key_hex))
canonical = json.dumps(
statement, sort_keys=True, separators=(",", ":")
).encode()
try:
key.verify(bytes.fromhex(signature_hex), canonical)
return True
except Exception:
return False
att = ... # the response of GET /v1/models/{id}/attestation
assert verify(att["public_key"], att["statement"], att["signature"])
What the statement proves
source.published_sha256vssource.measured_sha256: the file Civitai advertises is the file we actually fetched and compiled. Comparepublished_sha256against the Civitai listing yourself for end-to-end, no-trust verification.verified_source_identity/verification_method: the account that onboarded this model proved control of the Civitai listing.artifact.core_hash: the content address of the compiled weights being served — the same hash the serving pod loads by.- For endpoints:
components[]in canonical fuse order withscale— additive fusion is order-dependent at the bit level, so the order is part of the identity being attested.