Fingerprint Spec
When the Asqav SDK signs an action, it first builds a small fingerprint of the action data. This page is the public-facing summary of that format, so any verifier can rebuild it independently and check our signatures.
The full byte-level spec, with worked examples and edge cases, lives at docs/fingerprint-spec.md in the SDK repo. The same spec is committed in the backend repo and tested on every change.
The format
The fingerprint is RFC 8785 (the JSON format spec, also known as JCS) applied to the {action_type, context} pair, then SHA-256 over the resulting bytes. Five lines of stdlib Python:
import hashlib, json
def fingerprint(action_type, context):
payload = {"action_type": action_type, "context": context or {}}
body = json.dumps(payload, sort_keys=True, separators=(",", ":"),
ensure_ascii=False, allow_nan=False).encode("utf-8")
return "sha256:" + hashlib.sha256(body).hexdigest()
Output is sha256:<64 hex chars>. You send that as the hash field on /sign. Asqav signs it with the agent's ML-DSA key and returns a signature.
Cross-language guarantee
The Python SDK (asqav) and the TypeScript SDK (@asqav/sdk) produce byte-identical output for the same input. We ship conformance vectors at tests/conformance/vectors.json. CI on both SDKs runs them on every change, so the two stay in lockstep. If you write your own verifier in another language, run it against those vectors too.
Why it matters
Audits happen months later. If two implementations disagree on the bytes for the same input, signatures stop verifying and the audit trail loses its evidentiary value. The spec keeps the SDK, the backend, and any third-party verifier in lockstep.
By default on cloud, the SDK hashes the context locally and sends only the resulting sha256:<hex> value plus a small whitelisted metadata bag. The cloud never receives the context itself. That hash is unsalted unless the signer set an org_salt, so anyone holding the hash can test candidate contexts against it until one matches. See Privacy and Data handling for how this maps to GDPR Art 25 data minimization.
Full spec
The full byte-level spec is at github.com/jagmarques/asqav-sdk/blob/main/docs/fingerprint-spec.md. It covers the subtleties (float precision, Unicode normalization, tuples, datetime conversion, NaN/Infinity rejection) that any third-party implementer needs.
Related
- Governance Attestation uses the same JSON format for the attestation body.
- API Reference documents the
/signendpoint and both modes. - Data handling explains hash-only vs full-payload from the data-flow side.