Skip to main content

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?​