Skip to main content
Account sharing has a recognizable shape on the wire: one account, many devices, sometimes many countries in a short window. ShieldLabs gives you five layers to see it, including the Account sharing High-Risk Event, and you choose the action for each case (a paid seat is fine, a credential resold to fifty people is not).

What is account sharing?

Account sharing is when one set of login credentials is used across more people or devices than a plan allows: a password handed to friends, a single seat split across a team, or a subscription resold to many strangers. It shows up as one account appearing on more distinct devices and locations than a single user could plausibly produce.

How ShieldLabs surfaces it

ShieldLabs ties each identification of a signed-in user to the account and to the device behind it, and shows how far the account has spread. Five layers answer five different questions: The anchor for the rest is the durable Device ID, derived on the server, so a sharer cannot reset it by clearing cookies, opening an incognito window or switching networks. Counting an account’s devices by cookie or IP undercounts badly, because each of those reads as a fresh device; the Device ID holds steady, so a credential reused on the same device still resolves to one device instead of inflating the count.
Account sharing is a policy question. A family plan, a shared team login and a resold credential can all show as one account on many devices. ShieldLabs detects the sharing and shows the account’s devices; you choose the action for each case under your terms of service.

Prevent account sharing

When the Account sharing High-Risk Event arrives for a user through the API or webhooks, or when you review it in the analytics dashboard, act on the account: mark it in your own system, so its next sessions step up verification, notify the account owner, or restrict the extra sessions instead of letting one credential run everywhere at once. For a live check against your plan’s seat limit, count the distinct devices and countries per account, as the steps below show. Weigh a masked session more heavily: when a sharer uses a VPN to look local, local_ip, the address the browser itself reports, can show a different country from the public IP. ShieldLabs detects the spread and scores each identification with the Risk Score (0-100); you choose the action for each case in your backend. The steps below wire it up.

Build it

1

Create a ShieldLabs account and get your keys

Start Free with 5,000 identifications, one time, no credit card, or log in. In the analytics dashboard, add the domain you want to protect under Integration > Domains, then open Integration > API keys and copy its keys with the copy button next to each. The Public Key loads the snippet in the browser. Keep the server credentials on your backend: the Private API Key reads the History API, and each webhook endpoint has its own whsec_… signing secret. See API keys and Integration.
2

Identify authenticated sessions

Add the snippet to your app and pass the account’s hashed User HID with checkAuthenticatedUser on every signed-in page. Account sharing, Impossible travel and every account-level read below are built on it. When a session starts (right after login), call forceCheckAuthenticatedUser instead, so the new session always gets its own identification: a plain check is skipped when the same user was checked in this visit within the last five minutes. Pass a hash, never a raw email or user id.
app.html
3

Check the device on every session

Read the scored result for that request ID with the shared waitForScore helper (your webhook cache, falling back to the History API), then compare the Device ID against the account’s known devices.
api/session-check.js
Read the country with care behind a VPN. public_ip.country comes from the public IP, which a VPN exit can put anywhere. local_ip.country belongs to the Local IP, the address the browser itself reports, which can differ from the public IP behind a VPN or proxy; local_ip.ip is empty when the Local IP was not captured. When the two addresses differ, detection_flags.ip_mismatch is true. The flag is informational, adds nothing to the Risk Score and can be ordinary on mobile networks, so compare local_ip.country with public_ip.country rather than branching on the flag alone. A credential whose public_ip.country roams while local_ip.country stays fixed is more likely one masked location than real spread, so read the two together before you count an account’s countries.
One person using two browsers (Chrome then Safari) shows up as two devices, so “many devices” can include a single person’s own browsers, a nuance the identifiers reference explains. Weigh it with the country spread, the IP, and your own context before you treat it as sharing.
4

See the spread over time

Identification catches a new device right now. The harder signal is an account that quietly spreads across many devices, or appears in places one person could not reach in the time between them. ShieldLabs detects these on your users as High-Risk Events, each at Medium or High confidence, and they are available in the analytics dashboard, the API and webhooks. Events are a separate axis from the Risk Score and are keyed on the User HID you pass with checkAuthenticatedUser.
The user card for User HID c47a1e90b3d25f18 in the analytics dashboard: the Trusted band pill, a red Account sharing pill (High confidence), 14 identifications, all Trusted, and Linked devices open with 5 devices, each Trusted.The user card for User HID c47a1e90b3d25f18 in the analytics dashboard in the dark theme: the Trusted band pill, a red Account sharing pill (High confidence), 14 identifications, all Trusted, and Linked devices open with 5 devices, each Trusted.

An account with an Account sharing event in the analytics dashboard, with the devices linked to it.

One account used from several distinct devices. By default it fires from 4 devices on one account, and the threshold is configurable. The core account-sharing and account-resale shape, keyed on the User HID.
The same account active in locations it could not reach in the time between them. Catches a credential shared across regions; read it with the device spread.
An existing account appearing in a new environment that points to someone else using it. A takeover or hand-off signal, distinct from steady sharing.
To reconstruct the device and country counts live, read the account’s identifications from the History API with the shared accountView helper:
Count devices and countries per account
History reads on account.shieldlabs.ai and webhook delivery are free. High-Risk Events are available in the analytics dashboard, the API and webhooks. When an Account sharing event arrives for a user through the API or webhooks, or when you review it in the analytics dashboard, add the User HID, with the devices and local IPs linked to it, to a watchlist in your datastore; at the session check, check the incoming user_hid and device_id against it. The History API returns every device an account has used, by user_hid.
5

Tune to your product

A streaming service tolerates more devices than a single-seat B2B tool. Start in logging-only mode, watch how your real accounts distribute, then set the device and country limits in your own session check to match your terms.

Test it

Confirm the Device ID holds before you wire policy to it. Log in to one test account, then revisit on the same machine and browser in an incognito window and after clearing cookies: the cookie_id and visitor_id change each time, but the device_id stays the same, so one browser does not look like three devices. Then log the same account in from a second browser or a second device: a new device_id appears. That is the new device your check counts, and the reason your device limit should allow for one person’s own browsers. A guide, not a rule. The right device and country limits depend entirely on your product. A sudden device-and-country jump on an existing account can be sharing, but it can also be account takeover or the tail of a credential-stuffing run. The same Device ID and webhook payload feed all three, so once you have this wired you can branch on intent.

Next: Acting on results

The full decision playbook, including how to combine the account’s spread with the Risk Score of each identification and its signals.