Skip to content

How CooL works

Six steps, and you can check the output of every one.

Nothing in this pipeline is novel cryptography. That is deliberate — the primitives are standard, published and boring, and the only interesting decision is what gets committed to and who is allowed to check it.

The inference path (top) never passes through CooL. Capture is asynchronous and fail-open; the verifier sits outside the trust boundary on purpose.

Stage by stage

What each step actually computes.

  1. 01

    Capture

    An SDK call, a CI hook or a gateway hook notices the change. The call is an array push: asynchronous, bounded and non-throwing. It cannot block your inference and it cannot fail it.

    ChangeEvent
  2. 02

    Commit

    The event is serialised as deterministic CBOR (CDE). Determinism is the load-bearing property — two implementations must produce identical bytes, or every digest downstream means nothing.

    canonical bytes
  3. 03

    Bind

    SHA-256 over the canonical bytes, producing the binding digest. This is what makes tampering detectable rather than merely unlikely.

    binding_digest
  4. 04

    Sign

    ML-DSA-65 and Ed25519 over canonicalCBOR(core) ‖ binding_digest. Both are required. A classical break does not forge a record, and neither does a lattice break.

    hybrid signature
  5. 05

    Log

    An RFC 6962 leaf, SHA256(0x00 ‖ digest), appended to the transparency log. The audit path proves position in history rather than asserting it.

    leaf + audit path
  6. 06

    Verify

    Anyone, offline, with a verifier we do not control. Seven domains, reported separately. Two of them do not pass today and say so.

    seven verdicts

Post-quantum

Hybrid, never post-quantum alone.

Evidence has to outlive the machine that made it. A compliance record sealed today may need to be defensible in fifteen years — and a signature that becomes forgeable inside that window retroactively destroys every record it protected.

So every record carries two signatures: ML-DSA-65 (FIPS 204) and Ed25519. Both must verify. The reasoning is symmetric — the lattice schemes are young and could have an unpleasant surprise in them, and the classical schemes have a known expiry date against a cryptographically relevant quantum computer. Requiring both means a break in either family is survivable.

The same reasoning applies to key exchange: ML-KEM with X25519, together.

what gets signed
message = canonicalCBOR(core) ‖ binding_digest

  sig_pq        = ML-DSA-65(message, sk_pq)
  sig_classical = Ed25519(message, sk_ed)

verify → both must pass, independently

Keys

There is no signing key to configure.

There cannot be one. It is derived inside the enclave from the measurement of the image that is running — which is exactly why CooL cannot forge a customer's records.

Change the image and you derive a different key. That is not a side effect; it is the property that makes a measurement meaningful. A pinned measurement plus a derived key means “attested code” and “signing key” are one chain rather than two claims that have to be correlated by trusting somebody.

It also means there is no key escrow. We cannot produce a customer's signing key under legal compulsion, because we do not have one and the architecture gives us no way to obtain one.

Today this runs against a simulatorWhat that does and does not prove

Next

Watch it run, then try to break it.

The pipeline page runs all six stages in your browser and then gives you four buttons that forge the receipt, so you can watch the verifier reject it and name the domain that failed.