Skip to content
Guide · Fleet posture

Catch boot-config drift with cohort prevalence

Flag the one laptop whose bootloader nobody else in your fleet runs, without false-positiving the 999 that are fine. Every attestation already proves the hard things (real hardware, Secure Boot state, a clean boot chain); cohort prevalence adds one optional signal on top: how common is this device's boot configuration among devices like it?

It only ever tightens, never the gate.

Prevalence is an AND-constraint evaluated after every explicit check passes. It can add a reason to reject; it can never remove one. A device that fails Secure Boot or presents an emulated TPM is rejected no matter how common its profile is, so you can turn this on without weakening anything you already enforce.

What you decide

You don't compute anything — the cohort claims ride on every attestation for free. You decide two things: whether to gate on a prevalence floor in your policy, and which population to compare against. global is every device of the same make/model/firmware on the network (advisory); tenant-fleet is only your own managed devices — an empirical golden image you can safely hard-gate.

1

Client — nothing changes

The cohort claims are emitted on every appraisal, so your existing collect flow is all you need. The keyless client quotes the TPM over a nonce your server minted and posts the opaque evidence back:

client — keyless collectorts
import { attest } from "@rootherald/browser";

// Same collection you already do. Cohort claims come back in the server's
// verdict automatically — no flags, no extra round-trips.
const evidence = await attest(nonce); // nonce relayed from your server

await fetch("/api/session", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ challengeId, evidence }),
});
2

Server — read the claims and act on them

Appraise with rh.verify(); the verdict carries the cohort claims on verdict.device whether or not your policy gates on them. Read them, log them, alert on them — gating is opt-in.

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

const rh = new RootHerald({ secretKey: process.env.RH_SECRET_KEY! }); // rh_sk_… (backend only)

// Earlier: rh.issueChallenge() -> relay the nonce to the client.
const v = await rh.verify(body.evidence, {
  challengeId: body.challengeId,
  policy: "rootherald:builtin:strict-hardware",
});
if (v.device.verdict !== "pass") return forbid("device_check_failed");

// The explicit checks already decided pass/fail. These are the cohort signals,
// carried on verdict.device alongside the rest of the attestation result:
//   v.device.cohortPrevalence        number | null   weakest-link prevalence, 0–1 (null = cold start)
//   v.device.novelProfile            boolean | null  too rare, or cohort too small to judge yet
//   v.device.cohortScope             "global" | "tenant-fleet"
//   v.device.cohortSampleSize        number | null   distinct real devices in the denominator
//   v.device.cohortKey               string          opaque cohort id (to allowlist a profile)
//   v.device.cohortPrevalencePerPcr  { "0":…, "4":…, "7":… }   firmware / bootloader / Secure-Boot

if (v.device.novelProfile) {
  // A new-but-legitimate firmware build is novel until adoption grows. Don't hard-block —
  // log it, or require a step-up, depending on how sensitive the action is.
  await audit.log("novel_device_profile", { deviceId: v.device.ueid, sample: v.device.cohortSampleSize });
}

if (v.device.cohortPrevalence != null && v.device.cohortPrevalence < 0.01) {
  // Bottom 1% of its cohort — worth a second look for a sensitive action.
  await reviewQueue.add(v.device.ueid, { prevalence: v.device.cohortPrevalence });
}
Note
cohortPrevalence is the minimum across the three tracked low-variance PCRs: firmware (PCR[0]), bootloader (PCR[4]), Secure Boot policy (PCR[7]). If your firmware is common but your bootloader is one-in-a-million, you score one-in-a-million. A nullvalue means the cohort is still too small to estimate; handle it as "unknown," never as a silent reject.
3

Gate it in the dashboard (the 0–1 floor)

To enforce a floor instead of just reading the signal, set it on the policy your project uses. Open Dashboard → Policies, edit (or create) the policy, and open its Cohort prevalence (optional) section. Toggle Enforce a minimum cohort prevalence on; the slider is the 0–1 floor shown as a percentage — set it to, say, 5% (0.05). Then set the two behaviours that make it safe to turn on:

  • Cohort scope. Start with global (advisory: compared against the whole network, defaulting to warn). Switch to tenant-fleet once enough of your own devices are enrolled; that compares against your golden image and is the one you can safely hard-gate.
  • On novel profile. What happens below the floor (or when the cohort is too small): warn annotates the verdict and degrades the configuration trust vector (default, recommended while you tune the number); step-up demands a fresh re-attestation; reject contraindicates.

The recommended pairing once your fleet data is warm is tenant-fleet scope with step-up on novel profile: rare-for-your-fleet devices get a re-attestation challenge rather than a hard block.

Cold start is normal: start with warn.

A brand-new firmware build is legitimately rare until adoption grows, and a fresh tenant-fleethas too few devices to judge anything. That's why the default is warn and why prevalence reads null below the sample floor. Run in warn first, watch cohortSampleSize climb in your logs, then tighten to step-up / reject once the denominator is meaningful.

4

Allowlist the legitimate-but-rare ones

Some of your own devices will legitimately be rare — a new hardware refresh, a pre-release firmware. Those land in Dashboard → Cohort allowlist as a review queue that shows each novel profile with its cohortKeyand per-PCR values. One click approves a profile so it satisfies the constraint for your tenant's policies, without loosening anything for anyone else.