Skip to content

Product

The verify call returns a hardware fact about the device.

Add a challenge-and-verify pair to your signup, claim, or vote flow. The verify returns a plain pass or fail plus a stable, anonymous ID for the physical device, so you stop guessing whether a real machine is behind the request.

The answer — what your backend receivesjson
{
  "acr": "urn:rootherald:device:high",   // how strict a level the device met
  "device": {
    "ueid": "2f9c8a14…",                 // anonymous ID for this physical machine (no personal data)
    "earStatus": "affirming",            // affirming = the hardware vouched for it
    "verdict": "pass",                   // pass | warn | fail
    "attestationType": "tpm20",          // proved by a hardware security chip
    "secureBootVerified": true,          // the device booted trusted software
    "trustworthinessVector": { "hardware": 2, "configuration": 2 }  // confidence (higher = stronger)
  }
}
  • verdict: pass means accept the request; warn or fail means challenge or block it.
  • earStatus: affirmingmeans the hardware vouched for the device; warning and contraindicated mean be careful or don't trust it.
  • ueid: a stable, anonymous ID for the physical device, with no personal data. Use it to rate-limit or ban.
  • attestationType: the hardware security chip that proved the device.
  • secureBootVerified: the device booted trusted software.
  • acr: how strict a level the device met, for stepping up on high-value actions. trustworthinessVector is a confidence breakdown; higher numbers mean stronger evidence.

What you get

A proof you can branch on — not a score you have to trust.

Anonymous, hardware-tied device ID

A stable, anonymous ID for the physical device across Windows, Linux, macOS, Android, and iOS. It's tied to the security chip, not the OS install, so it survives a reinstall.

Rented-cloud and emulator detection

A fake that's really a rented cloud server or a software emulator chains to a cloud provider's certificate, not a real chip maker's. So it's rejected before it costs you anything.

Your rule for how strict to be

A policy is your rule for how strict to be. Pick a built-in one or write your own. Apply it per call, per session, or per project. No redeploy to change the rules.

Nothing to store

The verify call returns the answer in the response. Nothing to keep on your side; failover across regions happens underneath.

The integration

Check the proof. Branch on the answer. Store the ID.

On the device, the only job is to collect the proof. On your server, it's two quick calls (mint a challenge, then verify). Everything cryptographic happens on our side.

server · @rootherald/nodets
import { RootHerald } from "@rootherald/node";

const rh = new RootHerald({ secretKey: process.env.RH_SECRET_KEY }); // rh_sk_…
// Earlier: rh.issueChallenge() sends a one-time challenge to your app, which
// collects the device proof and posts back { challengeId, evidence }.
const verdict = await rh.verify(req.body.evidence, {
  challengeId: req.body.challengeId,
  policy: "rootherald:builtin:strict-hardware",
});

if (verdict.device.verdict !== "pass") {
  return res.status(403).json({ status: verdict.device.earStatus });
}
// verdict.device.ueid — a stable, anonymous ID for this physical device (no personal data)
await users.create({ ...req.body, deviceId: verdict.device.ueid });

Ship your first answer this afternoon.

Free up to 10,000 device checks a month, no card. Node available today; more SDKs rolling out.