Skip to content
Developers

Root Herald in three calls

Your backend holds the only key. A keyless client on the device answers a challenge; your backend appraises the answer and gets the verdict back on the same call.

server (Node) — the whole APIts
import { RootHeraldClient } from "@rootherald/node";
const rh = new RootHeraldClient({ secretKey: process.env.RH_SECRET_KEY! }); // rh_sk_…

// 1. Mint a challenge. It carries the nonce, the ask, and the policy.
const { challengeId, challenge } = await rh.issueChallenge({
  ask: ["identity", "posture"],                 // or ["key"] to mint a device-bound key
  policy: "rootherald:builtin:strict-hardware",
});
// 2. Relay `challenge` to the device verbatim; it answers with an opaque `evidence` blob.
// 3. Appraise it. A failing device is a verdict, not an exception.
const result = await rh.verify(evidence, { challengeId });
result.enrollmentRequired;   // first contact → relayEnroll / relayActivate, then verify again
result.device.verdict;       // "pass" | "warn" | "fail"
result.device.ueid;          // stable per-tenant device id, no PII
result.key?.jwk;             // only for a key ask, only on pass

What it is

  • A device proves it is a specific, real chip: a TPM 2.0 quote on Windows and Linux, the Secure Enclave on macOS, App Attest on iOS.
  • Every proof answers a single-use challenge your backend minted, so it cannot be replayed.
  • The challenge says what to prove (the ask: identity, posture, key) and which policy judges it.
  • The client holds no Root Herald key and never talks to Root Herald; it returns an opaque blob.
  • Your backend submits the blob with its rh_sk_ key and gets a verdict on that call. No token, no JWKS.
  • First contact on a machine is a one-time, two-leg enrolment that binds an attestation key inside the chip. Windows needs one elevation for it; nothing afterwards does.
  • The verdict carries a stable per-tenant device id, an EAR status, boot booleans, assurance claims, and optionally a certified public key.
  • A key ask mints an ECC P-256 key that cannot leave the chip; later requests are signed with it and verified locally with no Root Herald call.
  • Policies are named on the challenge and can be tightened at verify but never loosened.
  • Errors are string codes on a 4xx; a device that fails policy is a 200 with a failing verdict.

Guides

Clients

The server half is the same everywhere. Pick where the evidence is collected:

  • Browser — a web page; the Root Herald extension and native host drive the TPM.
  • Native — a desktop app, launcher or agent linking the C SDK.
  • Mobile — an iOS app with the Swift SDK, or a browser-only product via the companion app.

SDKs

API and reference