Every Registration Control We Shipped, They Answered Within Two Days. So We Stopped Chasing the Operator and Started Detecting the Shape.
- Patrick Duggan
- 4 minutes ago
- 9 min read
Most detection writing describes a control and stops there. The interesting part is never the control — it is what the other side does about it, and how fast. We got four days of that this week against a single operator, on our own free-tier registration form, and every observation below is our telemetry rather than somebody else's report.
The setup
On August 15 an audit found that 26 of the 103 API keys we had ever issued — 25% of every registration in our history — belonged to one operator, farming our Epstein document corpus past a 10-queries-per-day free limit. The pattern was mechanical: mint a key, burn six to ten queries, mint another.
A name-pattern sweep for "harborlight" found 12 of them. IP correlation found the other 14, registered from the same cloud hosts under entirely unrelated identities — proton, protonmail, tutanota, posteo, mailfence, gmail, and one temp-mail service. Seven cloud IPs across twelve email domains.
The identities were provably fabricated. Three of the newsroom domains — harborlight-press.com, harborlightpress.org, investigative-news.org — had no MX record and no A record. Those addresses physically cannot receive mail. A real newsroom does not run from Singapore cloud VMs with mailboxes that cannot accept email.
So we shipped two controls the same day.
MX deliverability. A registration email is the delivery address for the key itself. If we cannot mail it, it is not one. No blocklist required — this is a property of the abuse, not a name somebody remembered to enumerate.
IP-prefix velocity. More than three keys from one /24, or six from one /16. Per-IP counting misses rotation; the operator had used seven addresses but stayed inside two /16s.
Both verified against the real cluster. Both refused the fabricated newsrooms. Zero false positives on real prospects — cyware.com, stormshield.eu, rrcat.gov.in and our own partner all passed.
Day two: they stopped inventing newsrooms
August 16. Two more free keys, from [43.155.9.179](https://analytics.dugganusa.com/stix/register?ref=ioc-click&q=43.155.9.179) — the exact host that had minted the cluster's highest-burn key ten days earlier.
Neither control fired, and neither was broken.
MX: they registered on proton.me. Proton is a real mail provider with real users, it is on our known-good list, and we never look it up. That signal was spent against this operator in under 24 hours.
Velocity: the host held one prior key. The counts went /24=1, then /24=2, against a threshold of more than 3. They stopped at two. Prefix counting cannot see an operator who paces himself under the line.
The missing signal was not another property of the registration. It was memory — a host we have already proven bad should not get a third free key. So we shipped that: any IP, or its /24, that has ever had a key revoked for abuse is burned. Gated on the abuse reason specifically, because keys get revoked for billing corrections too and burning a paying customer's network off a billing fix is a worse outcome than the farming.
We deliberately did not burn the /16. 129.226.0.0/16 is all of Tencent, and refusing an entire provider is a much larger claim than "this host farmed us."
Day four: they bought the signal
August 18, 12:40 and 14:08 UTC. Two more free keys on the Epstein product, six queries each, from [8.210.6.238](https://analytics.dugganusa.com/stix/register?ref=ioc-click&q=8.210.6.238) — Alibaba Cloud, Hong Kong.
All three controls behaved exactly as designed. All three missed.
MX: one of the keys registered as [email protected]. That is the same fabricated newsroom domain we refused on the 15th. It now resolves, and it carries five Namecheap eforward MX records. They bought email forwarding — roughly twelve dollars — to defeat a check that had cost them nothing to trip three days earlier. The domain is now, in the narrow technical sense the control asks about, deliverable.
Velocity: two keys in the /24 against a threshold of more than three. Paced under it again.
Burned host: 8.210.x had never been used before. Memory only works on hosts you have already seen.
We also checked the obvious next idea before building on it. Domain age is useless here — harborlightpress.com was registered on 2025-01-05, nineteen months ago. They are not spinning up fresh domains; they are using aged ones. Every control we might have reached for next was already answered.
What actually held
Every signal they beat had one thing in common: it was a property the operator could change. An email domain can be bought. A registration rate can be slowed. A host can be swapped.
What cannot be changed cheaply is that a rented virtual machine in Hong Kong is not a person reading a document archive.
So the fourth control resolves the registration IP to its origin autonomous system, straight from the global routing table via Team Cymru's public DNS service. No API key, no vendor, no per-lookup cost, and no list of IP ranges anyone has to keep current ��� the same class of signal as the MX check, but anchored to the network rather than to a name.
The rule is deliberately narrow: free tier, plus the document archive, plus a cloud-compute origin, equals no free key. Not "no datacenter registrations," which would be wrong and expensive. Checked against every registration we have ever taken, a blanket version would have refused a real threat-intel vendor evaluating us from AWS, a corporate user behind a Zscaler egress proxy, someone on a gmail address inside Tesla's network, and a privacy-minded registrant coming through a consumer VPN. All four are legitimate. All four are on datacenter ASNs.
The asymmetry that makes the narrow version safe: our STIX feed is a machine feed, and a SIEM pulling it from EC2 is the normal, wanted case. The document archive is a human research tool with a ten-per-day allowance. A cloud VM registering for that is the farming shape and nothing else.
Replayed against all 110 registrations in our history: 28 of 28 abuse rows stopped, zero false positives on named real registrants. Three of the abuse rows are deliberately left to the burned-host layer instead — they registered for the machine feed, and a cash-poor defender running a SIEM on a five-dollar droplet with a gmail address is exactly who this platform exists for.
It is a shape, not a person
This is the part worth taking away, and it took us three tries to see it.
The first three controls were all memory of one adversary. A name-pattern sweep for "harborlight" remembers a name. A burned-host list remembers an address. A velocity threshold remembers a rate. Every one of them works beautifully on the operator who taught it to us, and every one of them is one purchase, one pause or one new host away from useless. Memory is a losing position, because the adversary always knows what you remember before you do.
The fourth control is not about that operator at all. It describes a shape: free tier, plus a human research corpus with a daily allowance, plus a registration arriving from rented compute. Anyone who walks into that shape gets the same answer, whether we have seen them before or not — no name, no prior, no list, nothing to look up.
That difference is the whole thing. A brand-new operator, first attempt, from a provider we have never listed, on a host nobody has ever burned, still gets refused — because the refusal is not a memory of anybody, it is a description of what free-tier farming looks like from the network side. The learned-ASN loop below sits on top of that as a second layer: enforcement teaches the gate which networks keep producing the shape.
It is the same argument our edge shield makes about blocklists, moved one layer up the funnel. A blocklist knows who was bad. A shape detector knows what bad looks like, which is the only one of the two that works on the person who has not arrived yet.
The part that surprised us
Once the two keys were revoked and marked as abuse, the system learned from its own enforcement inside a minute. The control counts abuse-revoked registrations per origin AS, and two from one network is enough to treat that network as compute regardless of whether we ever listed it.
AS132203 (Tencent): 26 abuse-revoked rows. AS37963 (Alibaba Hangzhou): 2. AS45102 (Alibaba US/HK): 2 — the last one added by today's enforcement, not by us. Every network this operator has ever used is now burned at the autonomous-system layer rather than one /24 at a time.
We are fairly sure this is a robot doing homework
The edge tells a consistent story. The requests carry curl/7.88.1, bare node, and one user agent that identifies itself as release-notes-verifier/1.0. The registration identities read like task names rather than people: task.authoring.probe, synth.authoring, sandbox-eval-2026, va.records.desk.
That is not a newsroom and it is not really a scraper either. It reads like an agentic evaluation harness minting a fresh key per task run — someone building or benchmarking an AI agent, using a real public API as the environment, and never noticing that the environment has a person on the other end reading the logs.
Which is fine. The policy has been the same since the 15th and it is not "go away," it is pay, not more free. Every refusal names a reason and points at either a paid plan or a human being at our end who will issue a key by hand for genuine sustained research. As of today it does that in fifteen languages, because the people hitting these controls registered from Hong Kong, France, Italy, Türkiye, Brazil, India and Morocco, and answering them all in English was its own small failure.
For the record, this was fun
There is a version of this post that is indignant. That version would be dishonest.
We keep a rule around here about arrows and dents: the dents are the record. A friend polishes your armour and it looks superb and you learn nothing. Someone shooting arrows at it tells you exactly where the plate is thin, and they do it for free, on their own schedule, without a statement of work. Every dent in this week is a place we could not see until somebody hit it.
Four days of somebody methodically probing our registration flow, changing exactly one variable at a time and paying real money to defeat a check, is free adversarial testing of a control surface nobody else was ever going to test. We do not have a red team. We had this instead, at a cost of about twelve dollars to them and roughly thirty free Epstein queries to us, and at the end of it we have a detector that generalises past the operator who provoked it.
We did not block them, and we still have not. Every refusal names a reason and offers a paid plan or a human at our end who will issue a key by hand for genuine sustained research. The policy since day one has been pay, not more free — and as of today the refusal says so in fifteen languages, because the people tripping these controls registered from Hong Kong, France, Italy, Türkiye, Brazil, India and Morocco, and answering all of them in English was its own small failure.
If whoever is running that harness is reading this: nice work on the MX records, genuinely. Mail us and we will sort out a key with a raised limit, and you can stop paying Namecheap for the privilege.
If you run a free tier
Three things this exchange is worth, generalised.
Detect shapes, not adversaries. A control built from what one operator did is a memory, and it expires the moment they change. A control built from what the behaviour is — rented compute asking a human corpus for free access — fires on the next one too, and the next one has not read your incident write-up.
Assume every control you ship is a signal the other side can price. Ours cost twelve dollars to defeat. That is not a criticism of the control — MX deliverability caught 26 keys and cost us nothing — it is an argument for stacking signals that have different prices, so the cheap one keeps working on the cheap adversaries.
Prefer properties of the network to properties of the submission. Anything typed into your form is chosen by the person filling it in. The autonomous system the packet came from is chosen by whoever they rented the machine from.
Let enforcement feed detection. The single best thing we built this week was not the ASN lookup, it was the loop where revoking a key teaches the gate which networks to distrust. It went from zero to three burned ASNs without anyone maintaining a list.
All observations are first-party: our registration table, our edge telemetry, and BGP data from Team Cymru. Timestamps are UTC. Confidence capped at 95%, as always — the fourth control will be answered too, and probably faster than the third.
Every indicator in this post is in the feed. Free.
1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.
Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=we-stopped-chasing-the-operator-and-started-detecting-the-shape




Comments