Tutorial: Evidence & Audit
Every QCOS job produces a cryptographically signed evidence bundle. Learn how to work with the evidence system for compliance, auditability, and trust.
Time: 10 minutes Β· Prerequisites: API key, at least one completed job
Overviewβ
QCOS evidence bundles contain:
- Job metadata β circuit, shots, backend, timestamps
- Results β measurement counts, fidelity metrics
- Hash β SHA-256 of all contents
- Signature β Signed by SoftQuantus CA
- Certificate chain β For independent verification
Step 1 β Run a Jobβ
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
from softqcos_sdk import QCOSClient
client = QCOSClient()
result = client.jobs.execute(
qasm="OPENQASM 2.0; include \"qelib1.inc\"; qreg q[2]; creg c[2]; h q[0]; cx q[0],q[1]; measure q->c;",
shots=1024,
backend="aer_simulator"
)
job_id = result["job_id"]
print(f"Job: {job_id}")
softqcos jobs run bell.qasm --shots 1024
# Note the job_id from output
Step 2 β Get Evidenceβ
evidence = client.jobs.evidence(job_id)
print(f"Bundle ID: {evidence['bundle_id']}")
print(f"Hash: {evidence['hash']}")
print(f"Algorithm: {evidence['hash_algorithm']}")
print(f"Signature: {evidence['signature'][:64]}...")
print(f"Created: {evidence['created_at']}")
softqcos jobs evidence <job_id>
Step 3 β Verify Evidenceβ
Verify that the evidence has not been tampered with:
verification = client.jobs.verify(job_id)
print(f"Valid: {verification['valid']}")
print(f"Signer: {verification['signer']}")
print(f"Certificate: {verification['certificate']}")
print(f"Verified at: {verification['verified_at']}")
softqcos jobs verify <job_id>
# Output: β Evidence valid (SHA-256, signed by SoftQuantus CA)
Step 4 β Get Full Bundleβ
The bundle includes all artifacts:
bundle = client.jobs.bundle(job_id)
print(f"Artifacts: {len(bundle['artifacts'])}")
for artifact in bundle["artifacts"]:
print(f" {artifact['name']:30s} | {artifact['type']:15s} | {artifact['size']} bytes")
softqcos jobs bundle <job_id>
Step 5 β List Artifactsβ
artifacts = client.evidence.artifacts(job_id)
for a in artifacts:
print(f"{a['name']:30s} | {a['type']}")
# Get a specific artifact
qasm_artifact = client.evidence.artifact(job_id, "circuit.qasm")
print(qasm_artifact["content"])
softqcos evidence artifacts <job_id>
softqcos evidence artifact <job_id> circuit.qasm
Step 6 β Download Evidence Packageβ
Download all evidence as a ZIP:
path = client.evidence.download(job_id, output_dir="./evidence")
print(f"Downloaded to: {path}")
# Contains: evidence.json, signature.sig, certificate.pem, artifacts/
softqcos evidence download <job_id> --output ./evidence/
Step 7 β Independent Verificationβ
Verify evidence offline using the public key:
# Get the public key
public_key = client.evidence.public_key()
print(public_key) # PEM format
# Verify hash independently
import hashlib
evidence_data = client.jobs.evidence(job_id)
computed_hash = hashlib.sha256(
evidence_data["content"].encode()
).hexdigest()
print(f"Matches: {computed_hash == evidence_data['hash']}")
# Get public key
softqcos evidence public-key > qcos_public.pem
# Verify locally
softqcos evidence verify <evidence_hash>
What's Next?β
- Calibration Flow β Calibration evidence bundles
- Multi-QPU Network β Network evidence
- Evidence API Reference β All methods