Skip to content

Use case · Free-tier abuse

Free tiers stop bleeding when each account costs a real device.

Stay generous without paying for 10,000 fake accounts. Hardware-rooted device identity makes the marginal cost of a fake account the cost of a physical computer.

The failure mode

The free tier costs more than the paid tier earns.

You ship a generous free tier: 100GB of bandwidth, $5 of compute credits, a starter API key. Within weeks, finance pings you: a large share of the signups are bots, scraper farms, or arbitrage operators stacking accounts to resell credits.

The usual responses are bad trades. "Require a credit card" throws away most of your real signup conversion to defeat the bots. "Require phone verification" costs you $0.01 per signup and gets defeated by SIM banks anyway.

The structural fix

One free claim per hardware-rooted device.

The device id is hardware-rooted (reformatting the OS doesn't clear it), per-tenant (it doesn't leak across products), and anonymous (you store no PII).

rate-limit free signups by device · @rootherald/nodets
import { RootHerald } from "@rootherald/node";

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

// Earlier: rh.issueChallenge() -> relay nonce to your dumb client, which
// collects the opaque evidence and posts back { challengeId, evidence }.
// Appraise server→server (cloud vTPMs and emulated TPMs are rejected by
// strict-hardware, so they come back as a non-pass verdict).
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({ error: "device_check_failed" });

// Already claimed free credits from this device?
const claims = await freeTierRepo.countByDevice(verdict.device.ueid);
if (claims >= 1) {
  return res.status(409).json({
    error: "device_already_claimed_free_tier",
    message: "Free credits are limited to one claim per device.",
  });
}

await freeTierRepo.claim({ deviceId: verdict.device.ueid, accountId: req.userId });

What this preserves

Real users never see a wall.

The integration is silent: your real signups never see a CAPTCHA, never receive an SMS, never install anything (OS-native attestation and the browser extension both flow through without a modal on modern hardware). Real users get the full free tier on first claim.

What you give up: customers who deliberately switch devices to claim multiple free tiers. That's a small population whose unit economics resemble paid customers anyway — you're not losing free-to-paid conversion you would have captured.

Layered

Stronger with email-domain limits on top.

Hardware id is the strong constraint; email-domain rate-limiting is a useful weaker one. Together: one device, one email domain → one free tier. Two real users in the same office share a domain but have different devices → both get credits. One attacker rotates emails but reuses the same device → blocked.

Keep the free tier. Lose the abuse.

Free up to 10K attestations a month, no card.