Skip to content

Remote attestation (RATS)

Xila Guard models GPU attestation along the RATS architecture (RFC 9334). It is an opt-in, default-off feature, and the distinction it protects is the one that matters most for credibility:

Simulation is never accepted by enforcement

The shipped verifier is a simulated one — it does no cryptography and uses ids of the form sim:*. A sim: id is never accepted by enforcement. Real GPU attestation requires confidential-computing-capable hardware (H100 / H200 / Blackwell-class) plus a real verifier (e.g. NVIDIA NRAS) that this project does not ship.

The category discipline

Attestation answers "what is this device, and what are its measurements?" — a different question from "who produced this report?" (that is identity). Xila Guard keeps them as two orthogonal features and never lets one masquerade as the other. SPIFFE identity attests a node/workload, never the GPU, and is never treated as attestation.

How the model works

AttestationEvidence (an RFC 9334 Attestation Result) rides as an optional Observation<AttestationEvidence> on a device. The EvaluationContext gains acceptedAttestationVerifiers and an attestationNonce.

flowchart LR
    EV[Device evidence] --> V[Verifier<br/>EvidenceDecoder + CryptoVerifier + AppraisalPolicy]
    V --> R[Appraised result<br/>Observation&lt;AttestationEvidence&gt;]
    R --> E[Pure evaluator<br/>no crypto here]
    CTX[acceptedAttestationVerifiers + nonce] --> E
    E --> OUT[indeterminate / deny / allow]

The pure evaluator does no cryptography. It consumes an already-appraised result and enforces:

  • provenance — the source must be attestation_verifier;
  • explicit verifier acceptance — the verifier id must be listed in acceptedAttestationVerifiers;
  • freshness — within the policy's age / skew limits;
  • nonce / replay binding and device binding;
  • outcome — fail-closed.

Outcome algebra, fail-closed:

Situation Result
missing / not-accepted / stale / unbindable indeterminate (ATTESTATION_REQUIRED / ATTESTATION_VERIFIER_NOT_ACCEPTED)
appraised outcome fail deny (ATTESTATION_FAILED)
no accepted verifiers configured (default) always indeterminate
accepted, fresh, bound, outcome pass contributes satisfied

Pluggable by construction

The verifier (the RATS Verifier role) is assembled from swappable traits so real crypto and formats drop in without touching the evaluator or the contract:

  • EvidenceDecoder — JSON today; EAT / CoRIM / COSE later;
  • CryptoVerifier — ring / rustls / openssl / COSE later;
  • AppraisalPolicy — reference values + nonce + claims;

composed by a ComposedVerifier and keyed in a VerifierRegistry. The shipped SimulatedVerifier (feature attestation-sim) is a trait implementation like any other — except its sim:* ids are only ever listed as accepted in offline / test contexts.

The gate that keeps simulation out of production

The single control is acceptedAttestationVerifiers: enforce / production contexts list only real verifier ids; sim:* appears only in offline / test contexts. There is no flag that can promote a simulated result into an enforcement allow.

Try it

cd xila-guard-lab && make demo-attestation
# accepted verifier  -> allow
# production context  -> indeterminate  (ATTESTATION_VERIFIER_NOT_ACCEPTED)
# appraised fail      -> deny            (ATTESTATION_FAILED)

CLI: xila-guard attest verify. Enabled with the Cargo feature attestation / attestation-sim; the default build and behavior are unchanged.

What a real integration still needs

A production adapter must verify fresh challenge binding, device identity, certificate chains, policy-relevant measurements, and revocation / reference information, bind the result to the allocated GPU and the intended relying party / session, and record the verifier version and verification time — using upstream libraries and formats, not invented cryptography. Hardware evidence does not by itself prove region, tenant exclusivity, application integrity, network segmentation, memory erasure, or whole-host integrity.

See the attestation & identity ADR.