SCITT, the Supply Chain Integrity, Transparency, and Trust working group at IETF, is the standards track for append-only logs that hold cryptographic statements about software, models, and now AI agent actions. Transparency services consume signed statements, append them to a Merkle log, and hand back inclusion proofs. The receipts have to be in a format the service understands. That format is COSE.
Asqav now exports any signed receipt as a COSE_Sign1 envelope on demand, so you can submit Asqav-signed agent actions to a SCITT transparency service.
Why SCITT
An organisation that wants third-party-verifiable evidence of agent behaviour does not want to run its own append-only log. SCITT separates the signer from the log operator. The signer says "I claim this happened". The transparency service says "I have witnessed and ordered this claim". A consumer checks both signatures and gets non-repudiable, ordered evidence without trusting either party alone.
For AI Act Article 12 records, DORA operational logs, and SOC 2 system descriptions, this two-party setup is what auditors expect for the next decade. Self-hosted log files do not pass that bar.
What COSE_Sign1 looks like
COSE, RFC 9052, is the CBOR analogue of JOSE. A COSE_Sign1 message is a four-element CBOR array:
- protected header, a serialised CBOR map with the algorithm and any required parameters
- unprotected header, a CBOR map for hints like the key ID
- payload, the bytes being signed (canonicalised receipt JSON)
- signature, the raw ML-DSA-65 signature over the Sig_structure
The whole envelope is wrapped with CBOR tag 18, which is how COSE labels a single-signer message. ML-DSA is registered with COSE algorithm identifiers in the IANA COSE Algorithms registry under the post-quantum group. Asqav uses ML-DSA-65, which corresponds to FIPS 204 parameter set 3.
The export endpoint
The on-demand export does not change the original receipt. It re-serialises the canonical JSON payload into a COSE_Sign1 envelope and re-signs with the same ML-DSA-65 key. The original JSON receipt and the COSE form are both first-class records, both verifiable independently.
curl -H "Authorization: Bearer $ASQAV_KEY" \
-H "Accept: application/cose" \
https://api.asqav.com/v1/receipts/{receipt_id}/cose \
-o receipt.cose
The response is the raw COSE_Sign1 bytes. Submit that to your SCITT transparency service of choice and you get an inclusion receipt back.
Verifying it locally
You do not need a SCITT service to inspect what came back. The CBOR is parseable with any COSE library. Here is a check using cbor2 in Python:
import cbor2
with open("receipt.cose", "rb") as f:
msg = cbor2.load(f)
# tagged value, tag 18 = COSE_Sign1
assert msg.tag == 18
protected, unprotected, payload, signature = msg.value
protected_map = cbor2.loads(protected)
print("alg label:", protected_map.get(1)) # 1 = alg
print("payload bytes:", len(payload))
print("signature bytes:", len(signature)) # ML-DSA-65 sig is 3309 bytes
The payload is the same RFC 8785 canonical JSON object you get from the regular receipt endpoint, so a verifier can re-extract it and compare against the JSON form for free. The signature is over the standard COSE Sig_structure, which means any compliant COSE verifier with an ML-DSA-65 implementation will accept it.
One key, two formats
The ML-DSA-65 key that signs your normal receipts is the same key that signs the COSE form. Auditors only have to learn one public key, and they can pick whichever envelope format their tooling supports. The two are bit-equivalent in payload, only the framing differs.
Where to start
- SCITT working group: datatracker.ietf.org/wg/scitt
- RFC 9052, COSE: rfc9052
- FIPS 204, ML-DSA: csrc.nist.gov/pubs/fips/204
- Asqav docs, COSE export endpoint: docs/cose-export
Run a SCITT transparency service in front of your Asqav signer and you have a two-party audit trail that any third party can verify, without contacting either of you.
Top comments (0)