Enroll only your devices
Let only yourmachines reach your admin console, source, or customer data. Root Herald gives every device a stable, hardware-bound identity that can't be cloned, exported, or moved to another machine. What it deliberately does not do is decide which devices are yours. You anchor that with a trusted enrollment moment, and this guide shows the pattern end to end.
Attestation can't tell a company laptop from a personal one: both have a TPM, Secure Boot, and factory keys. What makes “only your devices” true is trust on first use, gated by a secret you control: you hand a one-time enrollment token to a sanctioned device through a channel you already trust, and on its first passing attestation you record its hardware identity as enrolled. Your own service can hold the list; Root Herald just returns the hardware-bound, practically-unforgeable id.
1 · Cut a short-lived enrollment token (your side)
During onboarding, either behind your own auth or pushed to issued laptops by your MDM, mint a one-time, expiring secret. Root Herald never sees it; storing a hash is enough.
const enrollToken = crypto.randomUUID();
await db.enrollTokens.insert({
tokenHash: sha256(enrollToken), // store the hash, never the raw value
expiresAt: Date.now() + 10 * 60_000, // short-lived: 10 minutes
used: false,
});
// Deliver enrollToken to the sanctioned device ONLY — via MDM, or an
// authenticated onboarding link. This delivery channel is your trust root.2 · Appraise the device, check the token, persist the identity
During that gated onboarding the dumb collector posts an opaque evidence blob (no keys, no Root Herald contact) back to your backend, alongside your enrollment secret. Your server runs the Background-Check ceremony (mint a challenge, then rh.verify() the evidence) and requires both: a passing appraisal that meets your bar, and a valid, unused enrollment token. Then it records verdict.device.ueid as enrolled and burns the secret so it can never enroll a second machine: classic trust-on-first-use. The verdict comes back directly from rh.verify(); there is no client-supplied token to verify.
import { RootHerald } from "@rootherald/node";
const rh = new RootHerald({ secretKey: process.env.RH_SECRET_KEY }); // rh_sk_…
// (0) GET /onboard/challenge — mint a nonce and relay it to the device.
app.get("/onboard/challenge", async (_req, res) => {
const { challengeId, nonce } = await rh.issueChallenge();
res.json({ challengeId, nonce });
});
app.post("/onboard", async (req, res) => {
const { challengeId, evidence, enrollToken } = req.body;
// (a) appraise server→server; the verdict must clear your posture bar
const verdict = await rh.verify(evidence, {
challengeId,
policy: "rootherald:builtin:strict-hardware", // require strong posture at enroll
});
if (verdict.device.verdict !== "pass") return res.status(403).end();
// (b) the device must have presented a valid, unused enrollment secret
const row = await db.enrollTokens.findUnused(sha256(enrollToken));
if (!row || row.expiresAt < Date.now()) return res.status(403).end();
// (c) trust on first use: record the hardware identity, burn the secret
await db.enrolledDevices.upsert({ ueid: verdict.device.ueid, enrolledAt: Date.now() });
await db.enrollTokens.markUsed(row.id); // one-time: never enrolls a 2nd device
res.json({ enrolled: true });
});3 · Gate access to the enrolled set
From then on, no enrollment secret is needed again. Every sensitive request runs a fresh appraisal, reads the stable ueidstraight from the verdict, and checks it's one you enrolled. Because the identity is chip-bound, the evidence can't be replayed from another machine, and a device you never enrolled simply isn't on the list.
const { challengeId, nonce } = await rh.issueChallenge();
// ...relay nonce to the device, get back its opaque evidence...
const verdict = await rh.verify(evidence, {
challengeId,
policy: "rootherald:builtin:strict-hardware", // re-require posture each time
});
if (verdict.device.verdict !== "pass") return res.status(403).end();
if (!(await db.enrolledDevices.has(verdict.device.ueid))) {
return res.status(403).end(); // attesting live, but not one of your devices
}
// Enrolled + attesting live → let it through.This gives you a strong, honest guarantee: exactly one device enrolls per token, it held a valid secret you issued, and it passed attestation, and that device's identity can't later be copied to a personal laptop. It does notmean the device is “clean” or that we vetted that it's company-owned: the security of the enrollment moment is your delivery channel. Deliver the secret only to devices you sanction.
Don't want to run the secret yourself?
Root Herald already ships a one-shot, expiring linkTokenthat binds a passing attestation to a context, if you'd rather we hold the binding than build your own. And fully-managed enrollment, where Root Herald mints, burns, quota-limits, and audits the enrollment keys for you and signs an “authorized to enroll” claim right into the verdict, is a planned paid Device Trust feature, not yet available. The pattern above works today with nothing but the server→server rh.verify()call.