Account sharing

One password,eleven machines.

Every session returns the id of the machine behind it, so a seat shared across a team stops reading as one person.

one seat
This machine, as a row on the roster

running
signed in from
first_seen
sightings
01The roster

Two machines do the work on this account

The number of sightings per machine is what makes sharing visible.

One account, recordedlast 30 days
4b7e2a91c60d3f85MacBook Pro, SafariTallinnsince 3 Feb412
91c2f7d0a3b84e16Windows desktop, ChromeTallinnsince 12 Mar168
d05a13e8c4972bf6Windows laptop, EdgeRigasince 2 Jun9
77f1b3c50e2a9d84Android phone, ChromeWarsawsince 14 Jun6
ab34c9e10d7e5628Windows laptop, ChromeKyivsince 21 Jun4
c8e94a26b1035fd7Linux desktop, FirefoxBucharestsince 28 Jun2
4machines with fewer than ten sightings each

The two the account works from sit at 412 and 168 sightings.

SHARED
02The overlap

Three cities held the same session open

A password check never asks which machine is holding the session, so the overlap stays invisible to it.

TallinnMacBook Pro08:12
WarsawAndroid phone11:06
KyivWindows laptop12:42
3h 57mof one Tuesday with more than one machine signed inAT ONCE
03Your seat

Your own browser answers every question the roster asks

Read from the browser on this page
Which machine is this?identity.device_id
What is it running?device
Where did it sign in from?network
When did the roster first see it?identity.first_seen
How often has it been back?velocity.device
Does the id name a crowd?identity.degraded
Open every field this scan returnedon your own browser, in the playground
04Wiring

One call on the client, one row per machine

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

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

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

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

  // degraded marks an id a large cohort shares, so it names a crowd.
  if (identity.degraded) {
    return openSession(req, res);
  }

  // Your table: one row per machine per account, keyed on the id.
  await seats.record(req.user.id, identity.device_id, {
    first_seen: identity.first_seen,
    returning: identity.returning,
  });

  const seen = await seats.distinctSince(req.user.id, '30d');

  if (seen.length > SEAT_LIMIT) {
    return flagForReview(req.user.id, { machines: seen.length });
  }

  return openSession(req, res);
});
05Limits

What a device roster does not claim

A family shares a laptop and pays for one seatidentity.device_id
A household machine returns one id however many people use it, so the roster can show fewer machines than there are people.
Travel is not a second personnetwork
The id is read in the page, so moving to a new city changes the network reading and nothing else.
Some ids name a cohortidentity.degraded
A locked-down browser can produce an id a crowd shares, which inflates a seat count if you read it as a machine.
Only machines appear in the setidentity.linked_devices
Two ids that resolve to one machine are reported as linked. Who sits behind them is a question for TrustSig Pro.
06 Answers

Shared logins, answered

By the shape of the set, not its size. A person's own machines recur: the same three ids sign in week after week from the same city. A shared password produces ids that appear once, from networks that have nothing to do with each other, and the account's set keeps growing.

identity.device_id per session, identity.first_seen and identity.returning for whether that machine has been here before, and velocity.device for how often the project has seen it.

No. The reading happens in the page, so the id is the same whichever exit the request arrives from, and the connection is reported separately in the network block. A customer abroad reads as the same machine from a different country.

You can see two different device ids in overlapping sessions, which no password check can show you. Whether both are the account holder is a question about people rather than machines.

identity.degraded marks an id a whole cohort shares, which a locked-down browser can produce, so it shows up before you count seats. A household machine is one id with several people behind it, not an extra seat.

TrustSig Web reports the machines. Linking one device set to another account, and naming the person behind it, is TrustSig Pro.

Give every account its own roster.

One script tag, one server call, and the roster starts filling at the next sign-in.