Skip to content

Use case · Signup integrity

One device, one account — actually enforced.

Emails, phone numbers, and proxies all rotate for cents. The device is the one signup input attackers can't trivially rotate — if it proves itself with hardware-backed evidence, not a fingerprint script they control.

The problem

Fingerprinting catches the lazy bots. Nobody else.

Modern signup farms run on cheap inputs: SIM banks ($0.01/phone), disposable email domains ($0/email), residential proxies (~$3/GB). Fingerprinting catches anyone on stock Chrome and stock Windows, and misses anyone using GoLogin, Multilogin, AdsPower, or Kameleo, which synthesize plausible "fresh device" profiles for any number of fresh signups.

The thing that doesn't scale is a physical computer. Hardware is the only signup input that costs the attacker more per try than the marginal account is worth.

The fix

Bind the signup to a real, distinct TPM.

  • Every signup carries a hardware-attested device id (TPM, Secure Enclave, StrongBox, App Attest).
  • The id is stable per-tenant (same device, same id, forever), so 'one account per device' is a database check, not a CAPTCHA.
  • The id is anonymous: a per-tenant HMAC of the hardware key, not the key itself. No cross-tenant correlation, no key to harvest.
  • The device class is exposed (discrete hardware, firmware TPM, cloud vTPM, emulated), so you decide which classes count as real signups.

The integration

Three lines of business logic.

A device your acceptance policy rejects (cloud vTPM, emulated TPM) never reaches your handler at all.

server-side signup handler · @rootherald/nodets
import { RootHerald } from "@rootherald/node";

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

app.post("/api/signup", async (req, res) => {
  const { email, password, challengeId, evidence } = req.body;

  // Earlier: rh.issueChallenge() -> relay the nonce to your dumb client, which
  // collects the opaque evidence and posts it back here. Appraise server→server:
  const verdict = await rh.verify(evidence, {
    challengeId,
    policy: "rootherald:builtin:strict-hardware",
  });
  if (verdict.device.verdict !== "pass") {
    return res.status(403).json({ error: "device_check_failed" });
  }

  // Per-tenant device id — stable across this user's future logins, anonymous otherwise.
  if (await usersRepo.deviceAlreadyRegistered(verdict.device.ueid)) {
    return res.status(409).json({ error: "already_signed_up_from_this_device" });
  }

  const user = await usersRepo.create({ email, password, deviceId: verdict.device.ueid });
  res.json({ ok: true, userId: user.id });
});

The numbers

The break-even runs against the attacker.

A consumer signup is worth ~$2–$15 to a spam or arbitrage operator. A used OptiPlex with a TPM 2.0 chip retails for $50–$120: a break-even of 3–30 fake signups per piece of physical hardware, and only if the attacker keeps a wholly fresh OS-and-browser environment per signup without reusing the same TPM.

They can't. Our deviceId binds to the TPM, not the OS install, so reinstalling Windows doesn't reset it. The economics push the attacker toward buying real hardware in bulk (capital-intensive, detectable) or toward emulated TPMs (rejected outright by the default policy).

Enforce one device, one account, structurally.

No CAPTCHA, no SMS, no 'prove you're human' modal. Free up to 10K attestations a month.