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).
import { RootHerald } from "@rootherald/node";
const rh = new RootHerald({ secretKey: process.env.RH_SECRET_KEY }); // rh_sk_…
// Earlier: rh.issueChallenge() -> send the one-time challenge code to your app,
// which collects the sealed hardware proof and posts back { challengeId, evidence }.
// Verify server-to-server (rented cloud servers and software emulators 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", // our "real physical chips only" rule
});
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 (the check runs silently on modern hardware, and the browser version needs no popup). 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 device checks a month, no card.