# Sybil attacks: how one person drains your AI credits with a thousand free accounts

> Per-user caps don't stop signup abuse: a script that mints accounts gets a fresh budget every time. What the loss scales with, and what bounds it.

- URL: https://tokenpolice.ai/blog/sybil-attacks-on-your-ai-credits
- Published: 2026-09-13
- Author: TokenPolice Team
- Tags: free tier, abuse, cost

You ship an AI feature with a free tier and you cap it: every free user gets $5 a month, enforced. That holds right up until someone writes a signup script.

## The attack

A Sybil attack is one person pretending to be many. Register an account, spend its allowance, register another, repeat. Each new account starts at zero, so your per-user limit never trips and every user really is under $5.

The bill is a different story. A $5 cap over 1,000 accounts is a $5,000 exposure, and over 20,000 accounts it is $100,000. Your loss isn't bounded by the budget you set. It's bounded by how fast the attacker can fill in your signup form.

<img src="/screens/uc2-by-plan.webp" width="1186" height="400" alt="Cost by plan: free $14.46 across 27 users, paid $0.17 across 10" />

*The free tier costs 27 times more per head than the paid one. Nobody in it is over their cap.*

The tokens are real. The attacker is running their own workload on your OpenAI account, one throwaway identity at a time. Some of them resell the access, some just find it cheaper than buying their own key, and you pay either way.

## Why per-user caps miss it

A per-user cap protects you from one heavy user. It does nothing against many light ones, and a Sybil attack is many light users by design. Any limit keyed on identity resets for free every time the attacker mints a new identity, so the limit you want is keyed on something they can't multiply.

## Cap the whole tier

Put one shared budget across every free user: $25 total for the entire free plan, per hour or per day. Ten accounts or ten thousand, the pool is the same size. Every identity draws from the same counter, and when it's spent, free-tier calls pause until the window resets.

In TokenPolice this is one firewall rule. Pick the **Stop free-tier abuse (Sybil attack)** template.

<img src="/screens/sy1-template-picker.webp" width="2000" height="776" alt="Rule picker, Stop free-tier abuse (Sybil attack) highlighted" />

Name your free plan exactly as your app sends it in `paid_plan` (matching is exact, so `free` and `Free` are two different plans), pick the window, set the pool. Tick the per-user limit underneath so one account can't drain the pool alone. Start in dry-run to see what it would have paused, then switch to enforce.

<img src="/screens/sy2-rule-form.webp" width="956" height="1614" alt="Sybil rule form: plan free, hourly, $25 pool, $1 per user, dry-run" />

*A $25 hourly pool for everyone on `free`, a $1 inner cap per account, dry-run first.*

The rule runs before the provider call, so a tripped pool stops the spend rather than just recording it.

What this does is bound the loss. It doesn't identify the attacker: TokenPolice only sees the metadata your app sends, never IPs or devices, so keep your signup defences. And a shared pool is shared in both directions. When it trips, genuine free users wait too, so set it high enough to cover a normal hour or day.

[Cap the free tier](/docs/recipes/cap-free-tier) walks through the setup. The [solutions page](/solutions#sybil) has the longer write-up.
