Binding: Tying the Session to the Workload
You've proved what's running (Attestation). You've proved how it was built (Reproducibility). You've confirmed the measurement chain is intact. But none of that answers a simple question: is the client actually talking to that specific instance right now?
This is the B dimension of the KRAB model. Without binding, a perfectly measured, fully reproducible workload can still be impersonated, replayed, or man-in-the-middled.
The gap Binding closes
Attestation and Reproducibility prove how a binary was built and what trust boundary attests it. They do not prove that an externally observed session — an API call, a TLS connection, a key request — is tied to that specific attested workload instance.
Think of it this way: a quote says "this binary is running on this hardware." Binding says "and this session is connected to that specific running instance."
Without binding, the quote is a certificate hanging on the wall. Anyone can photograph it and wave it around.
How Binding works
The mechanism is the attestation quote's reportdata field (called report_data in Intel TDX, HOST_DATA or similar in other platforms). This is a 64-byte field that the workload controls — it can put anything in there before requesting a quote.
The binding protocol:
- The verifier sends a fresh challenge (a nonce — a random value used exactly once).
- The workload generates or accepts dynamic session data (the nonce, a session key, a TLS public key) and hashes it into
reportdata. - The hardware signs the quote — including the
reportdata— with its silicon key. - The verifier checks that the
reportdatain the quote contains the exact session data it expects.
Now the quote is not just "this binary is running" — it's "this binary is running, and it's the one I'm currently talking to in this session." The nonce ensures freshness. The hardware signature ensures integrity. The binding ensures identity.
The B levels
| Level | Name | What it means |
|---|---|---|
| B0 | Unbound | reportdata is zeroed, static, or unchecked. The quote proves nothing about the current session. Anyone can replay it. |
| B1 | Bound, Weakly Enforced | reportdata is used, but the content is static, stale, replayable, or only weakly validated. A fixed string. A reused nonce. An optional check. |
| B2 | Dynamically Bound & Enforced | The application generates or accepts fresh session data, hashes it into reportdata, and the verifier strictly enforces a match before proceeding. |
B0 — the silent failure
B0 is more common than you'd think. Many TEE demos and prototypes generate attestation quotes with reportdata set to zero or a fixed string. The quote is technically valid — the hardware signs it, the measurements are correct — but it's semantically meaningless for external verifiers.
An attacker who obtains a single valid B0 quote can replay it indefinitely. There is no way to distinguish a legitimate session from a replayed one, because no session identity was ever included.
In the KRAB equation, B = 0 means verifiability = 0. The architecture is fundamentally flawed.
B1 — the false sense of security
B1 covers systems that use reportdata but don't enforce it properly. Common patterns:
- A fixed nonce baked into the application (always the same — replayable)
- A stale challenge that's valid for hours or days (wide replay window)
- A verifier that checks the quote signature but ignores
reportdata(binding is cosmetic) - A nonce that's optional — the system works without it
These are better than B0, but they leave session-level vulnerabilities open. A man-in-the-middle who captures one session can potentially redirect verification to a different instance.
B2 — dynamic, enforced, fresh
B2 means the workload actively generates or accepts dynamic session data:
- A fresh nonce per verification request
- A session-specific TLS public key hashed into
reportdata - The verifier or KBS strictly rejects any quote where
reportdatadoesn't match the expected value
No exceptions. No fallbacks. Every session is uniquely bound to the specific instance at the specific moment.
Freshness and replay
Binding is inseparable from freshness. A nonce (number used once) is what makes binding work:
- Without a nonce: a quote from yesterday is indistinguishable from a quote from right now
- With a stale nonce: a quote from an hour ago might still pass
- With a fresh, unique nonce: only a quote generated for this specific request will pass
The freshness window matters. In high-security scenarios, the nonce should be unique per request. In some architectures, a short time-bounded window (seconds, not hours) may be acceptable. But "no nonce" or "static nonce" is always B0.
Alignment with A and K
Binding doesn't exist in isolation. To achieve full dynamic security, three dimensions must align:
- A3 provides a direct, non-mediated quoting path
- B2 carries fresh session identity into the quote
- K4 (covered in Key Release) verifies that same bound identity before releasing secrets
If any one drops, the system regains a session-level vulnerability. B2 on an A2 platform still works — but the binding flows through the CSP's paravisor, extending your trust boundary.
An application can be perfectly reproducible and silicon-measured, but if it is Unbound (B0), the quote is meaningless for external verifiers. Binding is not optional — it is what makes attestation useful beyond the hardware boundary.
Audit the reportdata field in your attestation quotes. If it's zeroed, static, or filled with a fixed string, you're at B0 regardless of everything else. The simplest upgrade: hash a fresh nonce from the verifier into reportdata and enforce the match on the verification side.