Offline Verification Walkthrough
How a regulator, auditor, or other agent verifies an Attestix Verifiable Credential without any network access.
This guide walks through verifying an Attestix-issued Verifiable Credential with no internet connection. All that is required is the public key of the issuer, which is embedded in the DID.
Scenario
You are a regulator. A supplier has sent you a Declaration of Conformity VC for their high-risk AI system. You want to confirm:
- The VC was signed by the claimed issuer.
- The signature has not been tampered with.
- The audit trail behind it is internally consistent.
No network calls. Everything should verify from the JSON blob and the public key.
Prerequisites
pip install attestixStep 1 / Fetch the artefacts
Ask the supplier to send:
- The Verifiable Credential JSON (Annex V Declaration of Conformity)
- The issuer's DID document (or the embedded public key)
- Optionally, the hash-chained audit trail export
All three come from export_compliance_pack:
from attestix.services.compliance_service import ComplianceService
pack = ComplianceService().export_compliance_pack(
agent_id="attestix:f9bdb7a94ccb40f1"
)
# pack -> zip with credential.json, did-document.json, audit.ndjsonStep 2 / Verify the signature
import json
from attestix.services.credential_service import CredentialService
credential_svc = CredentialService()
with open("credential.json") as f:
vc = json.load(f)
ok = credential_svc.verify_credential_offline(
credential=vc,
did_document_path="did-document.json",
)
# -> True (or False with a reason)Internally this:
- Canonicalises the VC with RFC 8785 JCS.
- Extracts the
proofValuefield. - Looks up the
verificationMethodkey in the DID document. - Verifies the Ed25519 signature per RFC 8032.
If the signature is valid, you have cryptographic proof that the issuer controlled the private key at signing time.
Step 3 / Verify the audit chain
from attestix.services.provenance_service import ProvenanceService
ok, first_bad_index = ProvenanceService().verify_audit_chain(
trail_path="audit.ndjson"
)
# -> (True, None) or (False, 42)Each entry is checked with SHA-256(prev_hash + canonical_json(entry_without_hash_fields)) = hash, where canonical_json uses sorted keys and compact separators. Any tamper with any row invalidates all subsequent rows.
Step 4 / Verify the declaration against the profile
ok = ComplianceService().verify_declaration_offline(
declaration_path="credential.json",
profile_path="profile.json",
)Confirms the declaration references the correct risk category, notified body, and covered articles.
Full example script
A runnable script is included in the repo at examples/offline_verify.py:
python examples/offline_verify.py ./compliance-pack.zipOutput:
[ok] signature verified (Ed25519Signature2020)
[ok] audit chain consistent (1,247 entries)
[ok] declaration references profile:3c8f21e9
[ok] 9 / 9 obligations met (Articles 9, 10, 11, 12, 13, 14, 15, 43, Annex V)
VERIFY = PASSWhy this matters
Every other compliance artefact you receive as a regulator comes as a PDF or a dashboard screenshot. Neither is cryptographically bindable to a specific operator or point in time. Attestix artefacts are.
The same function is what a peer agent calls when it decides whether to trust another agent's capability claim. See UCAN delegation for how delegation chains are verified the same way.
CrewAI Integration
Attach Attestix to every CrewAI agent via MCPServerAdapter. Production-ready in v0.3.0. Crews become attestable by default.
Base L2 Testnet Anchor Walkthrough
Anchor an Attestix artefact hash to Base L2 testnet via the Ethereum Attestation Service. End-to-end guide with Sepolia faucets, gas estimates, and verification.