Auth Protection
Prevent fake signups and account takeover with a blended IP, email, and browser-reputation verdict plus multi-account correlation on every signup and login.
One server-to-server call returns a blended IP, email, and browser-reputation verdict — plus multi-account correlation — for any signup or login. Drop the beacon on your auth pages, resolve the visitor from your backend, then flag, gate, or block on the verdict.
Your auth provider’s user.created webhook carries no IP, no user agent, and no browser context, so by the time a fake account or a takeover attempt reaches your backend the signals that would have caught it are already gone. Disposable emails, datacenter IPs, and one person spinning up dozens of accounts all look identical at the point you can actually block them. Auth Protection scores the visitor at the edge before the form is submitted, so the verdict is ready the moment your server creates the account.
When to use it
Reach for Auth Protection wherever an account is created or a session is established and you want to catch abuse at the point you can still block it — signup, login, password reset, or a step-up flow. A datacenter or residential-proxy IP on a consumer signup, a disposable email, or twenty accounts sharing one browser fingerprint are all invisible per-request but obvious here.
It complements the beacon and server reporting, which score full requests into your dashboard. Auth Protection is the synchronous, secret-key lookup you call from your backend at the auth decision point — and because the verdict only ever crosses back to a secret-key call, it is never exposed to the browser and cannot be tampered with.
How it works
-
Drop the beacon on your auth pages
Add the FormShield beacon to your signup and login views. It sets a first-party
_fscookie and scores the visitor at the edge — IP reputation, email signals, browser fingerprint, automation tells — before the form is ever submitted, so the verdict is ready when your server needs it. -
Resolve the visitor from your backend
On signup or login, read the
_fscookie server-side and callPOST /v1/sessions/resolvewith a secret key. It returns the edge verdict, session continuity (fresh, history-less sessions are themselves a tell), and multi-account correlation, then binds the account id you pass so future lookups stay linked even after the cookie is cleared. -
Flag, gate, or block on the verdict
Use the returned
decisionand the count of accounts sharing a fingerprint or IP to flag a signup for review, step up verification, or reject it. Because the verdict only ever returns to a secret-key backend call, it is never exposed to the browser and cannot be tampered with.
Quickstart
Read the _fs cookie server-side and send it, along with the visitor’s IP and the email and account id you’re creating, to POST /v1/sessions/resolve with your secret key (sessions scope). The beacon on your auth page must have already scored the visitor for a verdict to be ready.
curl -X POST https://api.formshield.dev/v1/sessions/resolve \
-H "Authorization: Bearer fs_live_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"session_id": "<_fs cookie read server-side>",
"ip": "203.0.113.42",
"email": "user@example.com",
"external_user_id": "user_2abc123",
"observation_type": "auth.signup"
}'The response carries the blended verdict, session continuity, multi-account correlation, and bound: true once the account id is linked:
{
"version": "1",
"data": {
"bound": true,
"verdict": { "score": 0.82, "decision": "review", "reasons": ["datacenter_ip", "shared_fingerprint"] },
"continuity": { "found": true, "first_seen": 1733500000000, "last_seen": 1733500120000, "age_seconds": 120, "observation_count": 3, "is_fresh": false },
"correlation": { "accounts_sharing_session": 1, "accounts_sharing_fingerprint": 7, "accounts_sharing_ip": 4, "linked_emails": 6 }
},
"error": null,
"metadata": {
"request_id": "req_a1b2c3d4e5f6",
"processing_time_ms": 38
}
}This response says: the visitor came from a datacenter IP and shares a browser fingerprint with six other accounts, so the blended verdict is review. Seven accounts share this fingerprint and four share the IP — the core fake-signup tell. Branch on verdict.decision and the correlation counts to decide whether to allow, step up, or reject the account.
The signals
Each call fuses four independent signals. No single tell decides the outcome — the blended verdict and the correlation counts are read together.
A single decision — allow, review, or block — fused from IP class (datacenter, VPN, proxy, Tor, residential proxy), email reputation, and browser fingerprint, with the reasons that drove it. The verdict crosses back only on a secret-key call, never to the browser.
Counts of distinct identities that share this visitor’s fingerprint, IP, or session. One person registering twenty accounts is invisible per-request but obvious here. This is the core fake-signup tell.
First-seen, last-seen, age, and an is_fresh flag. A brand-new, history-less session arriving straight at your signup form is weak but useful corroborating evidence of automation.
Pass external_user_id (e.g. a Clerk or Auth0 user id) and FormShield binds it to the visitor and persists the link in ClickHouse. Correlation survives a cleared cookie because the durable join is fingerprint plus IP, not the cookie alone.
The fields
The data payload groups the verdict, the continuity history, and the correlation counts. Branch on verdict.decision and the correlation counts together.
bound boolean Whether the external_user_id you passed was bound to this visitor. Once true, future lookups for the same identity stay linked through fingerprint and IP even after the _fs cookie is cleared.
verdict object The blended decision: score (0.0–1.0), decision (allow | review | block), and reasons — the tells that fired, e.g. datacenter_ip, shared_fingerprint. Fused from IP class, email reputation, and browser fingerprint.
continuity object Session history: found, first_seen, last_seen, age_seconds, observation_count, and is_fresh. A fresh, history-less session arriving straight at signup is weak but useful corroborating evidence of automation.
correlation object Multi-account linkage: accounts_sharing_session, accounts_sharing_fingerprint, accounts_sharing_ip, and linked_emails. High counts on fingerprint or IP are the core fake-signup tell — one person spinning up many accounts.
request_id string Identifier for the stored observation, prefixed req_. Correlates this resolve with its observation in the dashboard.
Endpoints
POST /v1/sessions/resolve endpoint path Live. Read the _fs cookie server-side and resolve the visitor: returns the blended verdict, session continuity, and multi-account correlation, and binds the external_user_id you pass. Secret key, sessions scope. A raw session resolve is 2 credits.
POST /v1/auth/check endpoint path Coming soon. A higher-level pre-flight that wraps the same IP, email, browser, continuity, and correlation signals into a single allow / review / block call for a signup or login decision. Until it ships, call /v1/sessions/resolve and branch on its verdict.
Common questions
How do I prevent fake signups with FormShield today?
Add the beacon to your signup page, then call POST /v1/sessions/resolve from your backend (secret key, sessions scope) when an account is created. The response gives you a blended IP/email/browser verdict plus a count of other accounts sharing the same fingerprint or IP, so you can flag, step up, or reject. This endpoint is live now. A higher-level POST /v1/auth/check pre-flight that wraps the same signals into a single allow/review/block call is coming soon.
Do I have to store risk data in my own database?
No. You pass your account id as external_user_id at signup and FormShield keeps the binding and history. To render risk later, call GET /v1/users/{external_user_id} for that identity’s current verdict, first/last seen, and multi-account linkage. The customer stores nothing; FormShield owns the identity-risk state.
What does this cost in credits?
Credits are weighted per operation: a signup check is 5 credits, a login check is 1 credit, and a raw session resolve is 2 credits. You meter and bill in credits rather than raw request counts, so heavier auth decisions cost proportionally more than a simple login.
Next steps
The IP reputation lookup behind the verdict — datacenter, VPN, proxy, Tor, and residential-proxy tags.
Disposable-domain, deliverability, and domain-age checks that feed the email signal.
Capture full requests — UA and IP together — including crawlers and AI bots.
The response envelope, authentication, and error codes.