Entity Attestation Token (EAT)

RFC 9711 Entity Attestation Token — a CWT (or JWT) profile that carries attestation claims describing the state of a device or software entity: a freshness nonce, a Universal Entity ID, OEM / hardware identifiers, debug status, software measurements, and nested submodule attestations. EAT is the token a Relying Party asks a device to produce to prove what it is and what state it is in. This module is the EAT profile over b.cwt — it maps the RFC 9711 claim names to their CWT claim-key integer labels and adds the attestation-specific verification.

b.eat.sign(claims, opts) takes a friendly claims object (nonce, ueid, oemid, dbgstat, eat_profile, measurements, submods, … plus the standard CWT claims) and signs it as a CWT.

b.eat.verify(eat, opts) verifies the CWT (signature + alg allowlist + time claims, via b.cwt) and then enforces the attestation contract:

- Nonce binding — when the Relying Party supplied a fresh expectedNonce, the token's eat_nonce (claim 10) MUST match it (constant-time compare). This is the freshness / anti-replay defense: without it a captured attestation can be replayed indefinitely. - Debug statusrequireDebugDisabled refuses a token whose dbgstat is enabled (0) or absent; only the disabled states (1–4) pass. - ProfileexpectedProfile pins the eat_profile claim.

Signing algorithms follow b.cwt / b.cose: ES256/384/512 + EdDSA (interoperable today) and ML-DSA-87.

b.eat.sign(claims, opts) #

stable0.12.35
{
  {
    alg:        string,   // COSE signing alg (ES256 / EdDSA / ML-DSA-87 / …)
    privateKey: object,   // signing key
    kid?:       string,
    tagged?:    boolean,  // CWT tag 61
  }
}

Sign EAT attestation claims into a CWT. EAT claim names map to their RFC 9711 integer labels; dbgstat accepts the enum name ("disabled-since-boot") or its integer. Standard CWT claims (iss / exp / …) pass through to b.cwt.sign.

var eat = await b.eat.sign(
  { nonce: rpNonce, ueid: deviceUeid, oemid: oem, dbgstat: "disabled-permanently",
    eat_profile: "https://example.com/eat/profile-1", iat: Math.floor(Date.now()/1000) },
  { alg: "ES256", privateKey: deviceKey });

b.eat.verify(eat, opts) #

stable0.12.35
{
  {
    algorithms:        string[],  // required — accepted COSE algs
    publicKey?:        object,
    keyResolver?:      function,
    expectedNonce?:    Buffer,    // require eat_nonce to match (freshness)
    requireDebugDisabled?: boolean,  // refuse dbgstat enabled / absent
    expectedProfile?:  string,    // pin eat_profile
    expectedIssuer?:   string,    // forwarded to b.cwt.verify
    expectedAudience?: string,
    clockSkewSec?:     number,
    now?:              number,
    externalAad?:      Buffer,
  }
}

Verify an EAT and return its attestation claims. Delegates the CWT signature + algorithm-allowlist + time-claim checks to b.cwt.verify, then enforces the attestation contract: the eat_nonce must match expectedNonce (when supplied — the freshness/anti-replay binding), requireDebugDisabled refuses a non-disabled dbgstat, and expectedProfile pins eat_profile.

var att = await b.eat.verify(eat, { algorithms: ["ES256"], publicKey: devicePub, expectedNonce: rpNonce, requireDebugDisabled: true });
// → { claims: { nonce, ueid, dbgstat: "disabled-permanently", ... }, raw: Map, alg }

Last updated 2026-08-08T16:39:49.652Z by seeder.