The first defence anybody reaches for against automated abuse is detecting automation. It is intuitive, the signals are well known, and it produces an immediate drop in the traffic you were worried about. It also produces a support ticket from a customer whose deployment pipeline stopped working, and that ticket is not a false alarm.
The problem is that the population of non-human traffic is not divided into people and attackers. It is a spectrum, most of it is either legitimate or actively invited by your own customers, and the signals that identify a headless browser cannot distinguish between an integration test and a credential stuffing run.
Who is actually out there
Before tuning any rule, enumerate the automation you are willing to serve. Customers run end-to-end tests against their own accounts in your product, often on every commit. They point uptime monitors at pages that require a session. They hire penetration testers who arrive looking exactly like an attack, because that is the assignment. Partners call your API on a schedule. And increasingly, software acts on a person's behalf with their credentials and their explicit intent.
Then there is assistive technology, which is the case that should end the debate. A screen reader, a voice control system or an accessibility bridge produces interaction patterns that look nothing like a mouse-driven human, and blocking them is both a product failure and a legal exposure. Any signal that fires on lack of mouse movement is a signal that fires on somebody who does not use a mouse.
- Customer test suites, running unattended against real accounts
- Monitoring and synthetic checks the customer configured deliberately
- Assistive technology, which is a person using a different input path
- Security testing the customer commissioned and forgot to tell you about
- Partner integrations and scheduled jobs, holding valid credentials
- Software acting for a user, with that user's knowledge and consent
Build the legitimate door and then point at it
Most illegitimate automation is aimed at a login form because there is nowhere else to go. Give the legitimate cases a sanctioned path — service credentials with defined scopes, a documented API, a way to mark a test account — and the population hitting the interactive form narrows considerably. Detection gets easier not because the signals improved but because the ambiguity was removed.
That path has to be easy to find and easy to use, or people will keep scripting the browser flow. Document it where an engineer will look, make issuing a credential a self-service action rather than a support conversation, and let it be scoped and revoked without anyone's involvement. The alternative is customers building fragile automation against your login page and you fighting it forever.
Most automation hits the login form because you never built anywhere else for it to go.
Weigh the false positive properly
A blocked attacker retries elsewhere at nearly no cost. A blocked customer loses a deployment window, opens a ticket and remembers it, and the incidents you never hear about are people who assumed the product was broken and stopped using it. The two errors are not symmetric and yet the same threshold controls both.
This is why graduated responses beat binary ones on any path a real user might reach. Adding friction, requiring a second factor, slowing a response or asking for confirmation all leave a legitimate participant a way through while making bulk abuse impractical. Reserve the hard block for signals with genuinely low false positive rates, and always leave a route back for somebody caught by mistake.
- Prefer added friction to a block on any path a real person can reach
- Let a customer allowlist their own automation for their own accounts
- Never use absence of mouse movement or a headless flag as sufficient evidence on its own
- Log what you blocked and why, in a form your support team can read back to a customer
Behaviour beats fingerprints
Client fingerprints answer what is making this request, which is the question you cannot reliably answer and which honest automation will answer for you anyway if you ask. Behaviour answers what is this request trying to achieve, which is the question that actually distinguishes abuse: many accounts from one source, one password against many accounts, a rate no interactive session could produce.
Those patterns are also stable. A fingerprint rule decays as clients change and needs constant maintenance; a rule about attempting sign-ins across many distinct accounts describes an activity that has no legitimate version. Spend the effort there, treat the client signals as one weak input among several, and you end up with a system that inconveniences attackers rather than one that surprises customers.
Everything here, already built
Sign-in, enterprise SSO, directory provisioning, roles and an audit trail behind one API. Start with the quickstart and have a working sign-in this afternoon.