New account fraud

The account is new.The machine is on file.

A fake account changes the email, the card, the window and the exit country. One verify call returns a device id that none of it moves, and the sightings behind it.

The key this signup would file under
Identityidentity.device_id

confidence
On filevelocity.device
--sightings
returning
first_seen
Arrived onnetwork
country
connection
vpn
datacenter
Reading this browser
01The run

Five accounts arrived on one machine

Each attempt cleared something the browser holds, and none of it reaches the machine the id is computed from.

09:41[email protected]first attemptresidential, Estonia
09:47[email protected]cookies clearednew emailresidential, Estonia
10:02[email protected]private windowresidential, Estonia
10:09[email protected]VPN exitnew emailVPN, Netherlands
10:31[email protected]new cardnew emailVPN, Germany
A recorded signup run

3c9d41e0b7a8f512

5accounts, one id, 50 minutes
ONE MACHINE
02Your machine

What this project has already seen of the browser reading this

--sightings of this machine by this project
5 min
1 hour
24 hours
7 days
30 days
identity
seen beforeidentity.returning
cohort-grade ididentity.degraded
machines resolvedidentity.linked_devices
Open every field this scan returnedthe whole response, on your own browser
03The gate

Decide on the machine the account arrives on

The first two rungs read the response, the last two read the accounts you have already bound to that id.

  1. 01Allowidentity.returning === false

    A first visit, with nothing on file against the machine.

  2. 02Bindidentity.returning === true

    Seen before, which on its own is a customer coming back.

  3. 03ReviewaccountsForDevice(id) >= 3

    Three accounts behind one machine, which a shared household can explain.

  4. 04BlockbannedDevices.has(id)

    A machine you have already ruled on.

04Wiring

Add the script, read the id on your server

signup.tsxCLIENT
import { useTrustSig } from "@trustsig/react";

const { getResponse } = useTrustSig();
const { token } = await getResponse();
signup.jsSERVER
import { TrustSig, hasReasonGroup } from '@trustsig/server';

const ts = new TrustSig({ secretKey: process.env.TRUSTSIG_SECRET_KEY });

app.post('/signup', async (req, res) => {
  const token = req.headers['x-trustsig-response'];
  const result = await ts.verifyRemote(token);

  // is_bot is true once the session crossed the block threshold.
  if (result.is_bot) {
    return res.status(403).json({ error: 'Access denied.' });
  }

  if (await bannedDevices.has(result.identity.device_id)) {
    return res.status(403).json({ error: 'Access denied.' });
  }

  // Your table, keyed on the device id. TrustSig supplies the key and the
  // sighting counts; how many accounts sit behind one machine is yours.
  const prior = await accountsForDevice(result.identity.device_id);

  if (prior.length >= 3 || hasReasonGroup(result, 'velocity')) {
    return queueForReview(req, res, {
      device_id: result.identity.device_id,
      accounts: prior.length,
    });
  }

  return completeSignup(req, res, {
    device_id: result.identity.device_id,
    trial: prior.length === 0 ? 'full' : 'none',
  });
});
05Limits

What the id does not claim

A device id is not a personidentity.device_id
A household laptop, a shared desk, a library machine. One id, several people behind it.
Some ids name a crowdidentity.degraded
A locked-down browser withholds enough of the surface that its fingerprint belongs to a cohort, and the response says so.
A fresh machine is a fresh ididentity.linked_devices
A second laptop defeats it, and the next account costs the hardware rather than another inbox.
Sightings count requests, not signupsvelocity.device
An ordinary customer reading your pricing page produces a dozen in one session, so the number measures traffic.
06 Answers

Repeat signups, answered

The scan runs on the signup form before the account exists, and the verify call returns identity.device_id with first_seen, last_seen and sightings. A repeat signup on a new email address arrives on an id you have already counted.

Yes. identity.device_id is computed from what the machine renders and reports, so there is nothing on the device to clear. A private window is reported separately as device.incognito: it changes what the page can store, not what the hardware draws.

Yes, and identity.degraded tells you how far the ban reaches: it marks an id whose fingerprint a large cohort shares. A library desktop, a household laptop and a hot desk all read as one id.

No. The reading happens in the page, so the id is the same whichever exit the request arrives from. The network block carries connection_type, vpn, tor and datacenter separately, so one machine signing up from four countries still reads as one machine.

Nothing. A different machine produces a different identity.device_id. identity.linked_devices reports when the graph has already resolved more than one id to one machine, and naming the person behind both is TrustSig Pro.

No. The id comes from the token alone, and nothing you collect in the form is sent to TrustSig. The id is scoped to your project, so it cannot be joined against another site, and the privacy note has the rest.

No. velocity.device counts how often your project has seen the machine, which tracks requests rather than accounts.

Put the id behind your own gate.

Your signup handler gets the identity block on the request it already answers.