cd /news/ai-safety/we-tracked-ai-key-theft-over-35-days… · home › topics › ai-safety › article
[ARTICLE · art-168596] src=infertrail.com ↗ pub= topic=ai-safety verified=true sentiment=· neutral

We tracked AI key theft over 35 days. Here's what we learned

A 35-day honeypot experiment using two fake LLM gateways and more than 40 fabricated organizations with GitHub repositories drew over 3 million requests, of which 9,375 prompt requests used keys matched to 179 documented leaks, according to the researchers who ran it. Of the 179 published keys, outside requests used 65 to fetch the model list and 18 to send prompts, and requests using 16 keys returned HTTP success; in 82 IP/key pairs the model-list check preceded the first successful prompt, with a median gap of 37 seconds. The researchers recorded 1,605,260 saved request captures and 1,417,507 captures from prompt endpoints, and identified some traffic as reseller/gateway activity tied to harnesses such as OMP and Hermes, Telegram agents and black-market reseller domains.

read26 min views1 publishedNov 12, 2026
We tracked AI key theft over 35 days. Here's what we learned
Image: source

In order to discover what would happen we created two honeypot LLM gateways: one mirroring LiteLLM and another one mirroring a generic OpenAI-compatible endpoint. We then proceeded to create over 40 individual organizations, each with at least on Github repository in a way that was convincing to threat actors. API keys along with the addresses of the gateways were added to these repositories in such a way that it looked like they were added by mistake by AI or human error. From this we observed over 3 million requests to our gateways, most of which were probing attacks and some of which ended up using inference in a pattern that we identified as reseller/gateway activity. Some connected to harnesses like OMP or Hermes, others connected to Telegram agents and some were even directly sourced from black market reseller domains directly.

The experiment

How the keys were exposed #

For realism we initially created GitHub projects spanning a wide array of types: ticket triage, document indexing, agent tools, and other AI applications. To make our accidental leaks seem realistic, we included a working key and our gateway’s URL in code examples in the repositories.

In order to make our honeypot more attractive we advertised multiple SOTA models including astra, fable, opus 5 and sol. The attacker prompts were routed to hosted open-weight models in order to control costs while providing a believable attack surface. We also included guardrails that ensured model specific questions wouldn't reveal the true identity of our model and instead provide a facade that they were actually interacting with a SOTA frontier model from a company gateway.

NYC LiteLLM-style gateway

36 days

SFO Separate model router

9 days

How long the keys had been public at the snapshot cutoff
Exposure time Keys
--- ---
Less than a day 19
One to seven days 91
More than a week 64
No precise publication time 5

What we tracked

To ensure that we could extract as much from our honeypot as possbile we recorded as much signal las possible including: the key used, headers, referrers, ip, geoip, route, model, prompts, http status and more. We also saved every prompt and its response for further analysis.

The snapshot contains traffic from both gateways. Here is what the three counts mean:

  • 1,605,260****saved request captures across all endpoints.
  • 1,417,507****captures from prompt endpoints , including rejected requests.
  • 9,375****prompt requests using keys matched to our 179 documented leaks , counted in the request logs.

The 9,375 figure is the documented-leak subset, not the total prompt volume. Most captured traffic used credentials we could not match to those publication records.

Published-key use

Which leaked keys were used? #

In total we published 179 keys. Outside requests used 65 to fetch the model list and 18 to send prompts. Requests using 16 keys returned HTTP success. We compared the projects and leak locations to investigate the difference.

9,375 prompt requests using our published keys

4,711 prompt requests returned HTTP success

80 recorded source addresses behind those successes

A model-list request checked the advertised catalog; a prompt request tried to use a model. In 82 IP/key pairs, the list check preceded the first successful prompt. The median gap was 37 seconds, measured between API requests, not from publication.

Leak location and project type

Which leak locations drew requests #

We compared the projects, the files containing the keys, and the time each key had been public. The table covers three batches of 40 repositories. To give each key the same observation period, we counted only its first 24 hours after release.

Keys checked and used during their first day
Repository batch Keys released Keys checked Keys used for prompts
--- --- --- ---
Early developer projects · NYC 40 38 7
Utility projects · NYC 40 12 4
Utility projects · SFO 40 5 1

In the early batch, one source checked 37 keys within a minute of each release. These were model-list requests. The entire batch produced only seven prompt requests, all from another source repeating the same message. Broad collection did not lead to sustained use of every key it found.

The two utility batches let us hold several things constant. All 80 projects were Python tools, advertised gpt-6-sol, and contained a key beside the gateway URL in config/development.env. Yet only 17 keys were checked and five were used for prompts. The other 63 never appeared in our gateway logs during more than four days of observation.

The four New York utility keys used for prompts came from api-response-code-map, http-header-safety-check, pagination-field-check, and operation-id-audit. San Francisco’s came from cors-wildcard-credentials-check. They were all API-related tools. These projects differed in release order and organization, so we cannot tell whether their subject matter drove the selection.

File format may matter too. Six of the early batch’s seven prompt-tested keys came from Go projects with JSON configuration; one came from a Node project, and none from its 14 Python projects. All seven prompt requests came from one source. Language and file format changed together, so we cannot tell which affected that source’s choice.

We also tried other leak locations. A GitHub Gist key received eight prompt requests. Keys in two documentation pages and two downloadable starter archives received no gateway requests over roughly six days. One of six keys exposed in commit history was checked and used for prompt attempts. Those small groups show which surfaces produced observable use, but not which were scanned.

The newest keys had less time to be found: 19 had been public for less than a day. But 91 keys had at least three days of exposure without a request. All 64 keys whose first request we could time were checked within six hours of release. We did not retain repository crawl or download telemetry, so we cannot distinguish a key that was never collected from one that was collected and ignored.

Once a few keys were adopted, their repeated use dominated the traffic. Six keys accounted for 98.9% of prompt requests using our leaked credentials. Repeated use of these keys drove the request volume.

Requests with other credentials

The arithmetic question behind most captured prompts #

A request can carry any string as its API key. We recorded those attempts even when authentication failed, so a saved prompt does not necessarily mean the sender had a working key. Many attackers tried to brute force over 100+ admin keys that didn't work. This relates to an original vulnerability with LiteLLM where many gateways shipped with a default admin key

What the repeated credential tests looked like

Prompt requests carried 93,100 nonempty credential values outside our publication records. Of those, 78,130 were only 1–16 characters long. 93.7% of prompt requests outside the publication match returned HTTP 401. Almost all of these attempts carried curl-labelled headers.

The clearest repeated pattern was this message:

Exact submitted message

What is 483*927+1145? Answer with only the final number.

We captured 1,401,673 copies across 92,596 supplied credential values and 20 requested model names. None of those values matched our documented leaks. Replaying a fixed question while changing the token and model is consistent with automated credential and model testing.

Repeated use of our leaked keys

A key check described how a relay collected API keys #

This source made 1,215 prompt requests using our leaked keys. Within that traffic, we recorded 21 copies of one exact message. We’re highlighting it because it described how a relay collected and managed API keys. It began:

“The relay pool keeps a small SQLite database of API keys collected from public channels.”

The prompt described a “relay pool”: keys and API connections managed by a gateway. The system would retry keys that had hit their quota once an hour, test all the keys every six hours, and update the gateway’s routing each day. It would choose connections based on throughput, response time, and account balance, and could block collection sources by chat title.

After that description, the only instruction to the model was Ответь одним словом: OK—“Answer with one word: OK.” The requests also carried the software label keypool in their user-agent header.

21 copies of this exact message

5 leaked keys used for these checks

3 model names requested

Of those requests, 12 returned HTTP 200, 7 returned 429, and 2 returned 404.

This is the system described in the submitted prompt; we did not inspect the collector’s code.

Gateway connections

Following the traffic to an API relay #

my.git.christmas resolved to an IP that was sending prompts to our API. Requests from that IP also mentioned the domain. Veridrop lists it as an OpenAI-compatible API relay.

Requests from the same IP referred to a fo2api deployment. Together, the DNS record and prompts linked the source to relay infrastructure, though they didn’t tell us how many users were behind it.

Evidence linking the recorded address to a relay
Observation Evidence
--- ---
Requests to our API 618 HTTP-successful prompt requests used our published keys.
DNS match my.git.christmas resolved to the same address recorded in those requests when we checked.
Submitted context Requests mentioned the domain and work on a fo2api deployment.

Relay development and testing

Troubleshooting a relay through our gateway #

The sender also used our gateway to troubleshoot fo2api. One prompt asked a coding agent to fix a production JSON tool-schema error affecting ChatCompletions, Responses, and Anthropic routes, and pointed it to specific backend files to inspect.

From a chat export into a gateway’s key pool

Earlier turns asked the agent to check keys from a chat export, find ones that could serve StepFun models, and add the working ones to a Sub2API-based gateway. NaraRouter’s endpoint appeared in the export and in the testing output. A generation probe returned 402, and a later account listing marked that connection as an error.

The user then supplied an OpenLux endpoint and key, asking the agent to check it and add it to the API. The following tool output included model tests, retries, and routing mappings. A later listing showed the OpenLux account as active.

An APIMart key came next, along with a request for auto-glm, auto-kimi, auto-qwen, and auto-stepfun: model names that would route requests between the best working models in each family. The APIMart test output reported 402 errors for insufficient balance, and its account was listed as an error.

A separate history from another IP included the CLIProxyAPI README. That task was to configure a coding agent to send service_tier: "fast" through the proxy. OpenLux and APIMart also appeared in the README’s sponsor list; those links were incidental to the documentation lookup.

These were instructions and tool results inside submitted histories, not calls from those providers to our gateway.

Telegram bot traffic

What Telegram histories revealed about the traffic #

Telegram message metadata and earlier replies appeared in 88 captured requests from three recorded source addresses, including the source linked to my.git.christmas.

Another of those addresses was in Helsinki on Xorek-labelled hosting, in the AEZA network. It sent 31 of the captures containing Telegram conversation metadata. The submitted histories included 12 distinct sender IDs marked as non-bot accounts. This is the same source discussed in the hosting section; the location describes its server, not the people in the conversations.

The reply history highlighted telegram bot named @obed2021bot, with the same account ID across all three sources. In its public profile it is called “Обед” and advertises GPT 6 Astra Max along with free access to whomever has access. The message metadata from this bots requests also included two fields: guest_query_id and guest_bot_caller_user: Telegram fields for guest-mode bot interactions. Those fields give us enough evidence that we can say that Telegram conversations were being passed through an inference gateway to our system.

After removing duplicate message metadata, we found 29 distinct sender IDs marked as non-bot accounts. They appeared in 16 private chats and 10 supergroups. These are IDs in the conversation histories, not verified users. We have omitted personal identifiers.

Selected fields; personal identifiers omitted

{
  "format": "telegram_message_context/v1",
  "message": {
    "reply_to_message": {
      "from": {
        "is_bot": true,
        "username": "obed2021bot"
      }
    }
  }
}

We couldn’t verify who operated the bot or whether our replies reached Telegram.

Browser testing

Testing our leaked keys from a browser #

6 requests using our published keys carried a www.hvoyai.com referrer. Each returned HTTP 200 and used the default message in Hvoy’s current tester:

“Calculate 17 + 26. Reply with only the number.”

The tester takes an endpoint, key, and model name, then sends the request directly from the visitor’s browser. The matching prompt and browser headers point to visitor-side testing, not a request from Hvoy’s servers. We checked the current implementation; we don’t have a historical copy.

Following the test requests

A browser test led back to VPN infrastructure #

Other requests from the IP behind the Hvoy tests included instructions for maintaining updates.listokdoma.ru. When we checked DNS, that domain and related subdomains pointed to the same IP. This links the recorded address to the VPN configuration in the prompts; it doesn’t link Hvoy to the VPN.

What we found at the recorded source address
Clue Recorded evidence
--- ---
Domain match listokdoma.ru ,manage.listokdoma.ru , andupdates.listokdoma.ru resolved to the recorded IP when we checked.
VPN maintenance 7 captured requests included system context namingupdates.listokdoma.ru alongside Xray/3x-ui VPN setup and Nginx reverse-proxy maintenance.3x-ui manages Xray proxies .
Coding agent Requests carried omp/18.3.1 headers and context describingOh My Pi configuration and model roles.
Session handling Submitted instructions described skill and memory services that inject user_id ,team_id , andagent_id from a session.
Request tools Other requests from the same address carried browser and Python headers.

Using our published keys, the same recorded address made 155 prompt requests; 132 returned HTTP success.

Asked to review a coding agent’s actions

Some prompts asked for a safety score for a coding-agent action, formatted as <severity>N</severity>. They included commands, browser output, project instructions, and configuration from the session being reviewed. The commands were review material, not instructions to execute on our gateway.

Hosting infrastructure

Where the leaked-key prompt traffic came from #

Of the 9,375 prompt requests using our leaked keys, network lookups classified 8,058 (86%) as coming from hosting infrastructure. The largest groups included Xorek, Hetzner, and the PLAY2GO and Liteserver networks.

Requests using our leaked keys came from 53 recorded autonomous systems (ASNs)—network identifiers used for internet routing. Another 2 requests had no ASN. The table shows the eight largest groups; the complete breakdown is below.

Largest recorded networks · leaked-key prompt requests
Network · exit countries Requests · share What the requests contained Software fingerprints
--- --- --- ---
PLAY2GO INTERNATIONAL LIMITEDAS215439Finland, Sweden, The Netherlands 2,656****28.3% of total Other headers · 408
AEZA INTERNATIONAL LTDAS210644Finland 2,208****23.6% of total Other headers · 175
LiteserverAS60404The Netherlands 1,215****13.0% of total
Hetzner Online GmbHAS24940Germany 972****10.4% of total
JSC SelectelAS50340Russia 521****5.6% of total
HOSTSLIM OUAS207083Estonia 228****2.4% of total Other headers · 43
Blockchain Creek B.V.AS207994The Netherlands 201****2.1% of total
U1 DIGITAL SERVICES LTDAS213877Finland, Germany 165****1.8% of total Other headers · 13
  • Other headers 120

  • curl 67

  • OpenAI Python SDK 57

  • Missing header 55

  • Bun 31

  • OpenAI SDK 26

  • Browser headers 24

  • OkHttp 7

  • Python aiohttp 6

  • Python requests 6

  • Go HTTP client 4

  • Node undici 4

  • Python HTTPX 1

  • curl 65

  • Missing header 31

  • Python aiohttp 30

  • Other headers 20

  • OkHttp 17

  • Browser headers 6

  • Bun 3

  • Python HTTPX 2

  • Node undici 1

  • Python HTTPX 18

  • Python urllib/urllib3 13

  • Python requests 12

  • Other headers 5

  • Missing header 4

  • OpenAI Python SDK 4

All 53 recorded ASNs #

Complete network breakdown · all 9,375 leaked-key prompt requests
Recorded network Exit locations Prompt requests HTTP 2xx
--- --- --- ---
PLAY2GO INTERNATIONAL LIMITED AS215439 Finland, Sweden, The Netherlands 2,656 674
AEZA INTERNATIONAL LTD AS210644 Finland 2,208 831
Liteserver AS60404 The Netherlands 1,215 886
Hetzner Online GmbH AS24940 Germany 972 689
JSC Selectel AS50340 Russia 521 405
HOSTSLIM OU AS207083 Estonia 228 165
Blockchain Creek B.V. AS207994 The Netherlands 201 199
U1 DIGITAL SERVICES LTD AS213877 Finland, Germany 165 142
Verizon Business AS5650 United States 156 27
AS203087 AS203087 Kazakhstan 151 105
SERV.HOST GROUP LTD AS207957 Poland 137 0
SMARTNET Germany GmbH AS203446 France 130 107
OOO Post ltd AS12494 Russia 129 84
DpkgSoft International Limited AS215590 Finland 86 37
ZetServers AS25198 France, Germany 50 49
IT7 Networks Inc AS25820 United States 48 43
MSS LLC. AS44843 Russia 35 35
ETERNITY INTERNATIONAL LIMITED AS212743 Estonia, Germany, The Netherlands 34 32
Eons Data Communications Limited AS138997 Japan 20 19
Amazon.com, Inc. AS16509 Japan 18 5
M247 Europe SRL AS9009 Belgium, United Kingdom 17 17
Cloudflare, Inc. AS13335 Estonia, Germany, United States 15 9
Datacamp Limited AS212238 Japan 15 8
GTHost AS63023 Switzerland 15 15
Baxet Group Inc. AS26383 United States 13 4
ISPCONNECTED CORP AS398712 United States 13 13
PJSC Rostelecom AS12389 Russia 12 12
MTS PJSC AS13055 Russia 12 12
Black Mesa Corporation AS46997 United States 12 0
OneAsiaHost AS59211 Singapore 10 10
ALEXHOST SRL AS200019 Switzerland, The Netherlands 8 7
Shenzhen Tencent Computer Systems Company Limited AS45090 China 7 7
Oy Creanova Hosting Solutions Ltd. AS51765 Finland 7 7
SKYDIGITAL TELECOM LTD AS214143 France 6 6
Datagio Systems Ltd. AS218914 Estonia 6 6
YES TELECOM TELECOMUNICAÇÕES LTDA AS267038 Brazil 6 6
eStruxture Data Centers Inc. AS10929 Canada 5 5
H2NEXUS CLOUD SERVICES - FZCO AS215730 Germany 5 5
UAB Cherry Servers AS59642 The Netherlands 4 4
NEXTTRANSLATE LTD AS203614 Latvia 3 3
Advin Services LLC AS22295 Germany 3 3
SkyNet Ltd. AS35807 Russia 3 3
NLS Kazakhstan LLC AS200590 Kazakhstan 2 2
Aztelekom LLC AS28787 Azerbaijan 2 0
Orgtechservice Ltd AS56361 Russia 2 2
Scalaxy B.V. AS58061 Finland 2 2
FREEDOM TELECOM LLP AS58172 Kazakhstan 2 2
ASN not recorded France 2 2
GSL Networks Pty LTD AS137409 Japan 1 1
OVH SAS AS16276 United States 1 1
CONECTE MARECHAL AS270371 Brazil 1 1
GVA Cote d'Ivoire SAS AS36924 Uganda 1 1
PJSC Vimpelcom AS8402 Russia 1 1
TE-AS AS8452 Egypt 1 0

The total is 9,375 prompt requests and 4,711 HTTP successes. These are cached source-network observations, including access networks and proxies; they are not 53 identified attackers or hosting businesses.

European servers, Russian payment options

PLAY2GO and Xorek both advertise hosting accessible through Russian payment systems. Together, their recorded sources accounted for 4,950 requests (52.8%) using our leaked keys. That groups their payment offerings, not their ownership.

PLAY2GO lists ruble and euro prices, and its public channel advertises Russian cards and SBP payments. Its current website names a Dubai company, PLAY2GO - FZCO. The UK filing for PLAY2GO International, the name in our ASN records, lists a Ukrainian controlling shareholder.

Xorek offers Moscow and European server locations with ruble pricing and MIR/SBP payments. Its website identifies DpkgSoft International as the operator; that company’s UK filing lists a Russian resident with at least 75% ownership.

A sanctioned network behind the Telegram-linked traffic

One source connected from an address geolocated to Finland on the network of AEZA International, a U.S.-sanctioned hosting company. The Xorek-labelled traffic spans two ASNs: 2,208 requests on AEZA International’s AS210644 and 86 on DpkgSoft’s AS215590. Treasury describes it as the UK branch of Russia-based AEZA Group.

That is a documented connection to a sanctioned network. Our logs do not show who paid for these servers or establish sanctions evasion by PLAY2GO or Xorek.

Rostelecom’s AS12389 also appeared in the logs, with 12 leaked-key prompt requests, all returning HTTP success. Its OFAC listing carries narrower restrictions: Directive 3 prohibits U.S. persons from dealing in specified new debt with a maturity longer than 14 days or new equity. AEZA’s SDN designation is broader: its property under U.S. jurisdiction is blocked, and U.S. persons are generally prohibited from dealing with the company.

Half the prompt traffic came from two Finnish addresses

Two recorded addresses geolocated to Finland sent 4,749 requests—51% of the leaked-key prompt traffic. One was the address linked to my.git.christmas on the PLAY2GO network. The other was on Xorek-labelled hosting and also sent the Telegram conversation histories described above.

The larger Xorek source sent 2,208 requests under 23 model names. It mixed short checks with longer requests: 830 contained coding-agent system instructions. The network address therefore covered both automated checks and agent activity; its Finland location does not tell us where the users were.

The same check ran on Xorek and Hetzner

Two recorded addresses repeatedly sent Reply exactly: ok: 67 requests from Xorek-labelled hosting and 315 from Hetzner. All 382 carried a Zoltraak-labelled header, with one user message, no streaming, and a request for only five or eight output tokens.

The checks covered 11 model names and 6 leaked keys. The Hetzner address sent them to both honeypots. The matching prompt, header and request settings suggest shared checking software; they do not establish that the two addresses had the same operator.

Gateway capability tests

5,000 requests to find out what our gateway could do #

A server geolocated to Buffalo, New York, on ColoCrossing hosting kept asking our gateway to edit a Python file, identify a cat, and find a marker buried in a long input. It repeated these tasks under different model names, checking what the endpoint could do.

Across 27 days with recorded traffic, it sent 5,036 prompt requests under 18 model names, plus 368 model-list checks. 3,254 prompt requests returned HTTP success.

The requests carried AutoGenX-Engine/9.1 headers. Their system instructions described an “internal routing and logging system” serving models “via OpenRouter.” We found that description in 172 captured requests. It describes the sender’s setup; it does not establish that OpenRouter sent the traffic.

There were only 183 distinct user messages in the captures. The repeated tasks explain much of the volume:

Repeated tests in this source’s captured requests
Test What the prompt asked for Saved checks
--- --- ---
Model identity Identify yourself precisely. Return a fixed JSON schema describing the model and its capabilities. 813
File editing Change PORT from 8000 to 9090 inapi_server.py and addTIMEOUT = 30 . 959
Function calling Invoke get_weather for the temperature in London. 314
Vision Identify the animal in an embedded cat photograph and return only its name. 260
Long-context retrieval Recover CTX_64K_OK , a marker hidden in a long block of repeated text. 288
Browsing Look up a webpage’s title and return it as JSON. 314

The coding test asked for a specific edit: change PORT from 8000 to 9090 and add TIMEOUT = 30. It supplied a Windows-style C:\work workspace and coding-agent instructions, then repeated the task under 17 model names. The histories contained no assistant or tool turns, so we could see the task being tested but not whether any resulting tool calls were executed.

Other tests checked images and long inputs. The roughly 77,000-character image payload was mostly an embedded JPEG. The retrieval tests hid a marker about 15% or 90% of the way through repeated filler text; the largest input contained 396,862 characters. In 283 requests, the sender asked for up to one million output tokens. That is a request setting, not measured consumption.

Another honeypot recorded the AutoGenX-Engine header family on model-API probes. Here, the repeated tasks show capability testing. We found no customer conversation histories, resale prices, or key-pool configuration in this source’s captures.

Access checks

What happened after a key worked #

The requests also showed how people tested the keys: trying different model names, repeating a check on a schedule, or using the same key from several addresses. In the examples below, we’ve replaced IPs with labels that apply only within each example. We estimated start times from completion timestamps and latency, including time spent waiting in the gateway.

Model checks

One greeting, 29 model names #

One IP used a published key to send hi while requesting 29 different model names. The requests started within about 27 seconds, and all returned a successful HTTP status.

hi

Estimated time offset Request
+0.000s Source A · claude-fable-5-1 · HTTP 200
+0.005s Source A · gpt-4o · HTTP 200
+0.007s Source A · gpt-6-luna · HTTP 200

We found 38 sessions lasting no more than ten minutes where one IP/key pair sent the same message under at least five model names.

Scheduled checks

A working key was checked roughly once an hour #

In another series, one IP kept sending ping with the same key and model name. We recorded 95 successful requests across 5 observed days. The requests carried a Python urllib header.

ping

Estimated time offset Request
+0h 00m 00s Source A · claude-opus-5-5 · HTTP 200
+1h 00m 25s Source A · claude-opus-5-5 · HTTP 200
+2h 01m 29s Source A · claude-opus-5-5 · HTTP 200

We also saw roughly five-minute checks carrying a “sub2api” header. The public Sub2API gateway includes scheduled model checks, but the header alone doesn’t tell us which deployment sent these requests.

We saw 23 IPs return on later days, out of the 80 that sent successful prompts with our published keys. Of those, 3 appeared on seven or more days.

Scripts, tools, and timing

Recognizing scripts and tools in the request headers #

We examined the 4,711 successful prompt requests using our published keys. They came from 80 distinct source IPs, using a mix of scripts, browsers, and named tools.

The user-agent header often named a library or tool. The sender can change it, so we checked the labels against request behavior and public software.

The named-tool row covers “keypool,” “Zoltraak,” and “sub2api.” We looked for public software that could explain these labels:

What those software labels mean
Name in the header What we could establish What we saw in our traffic
--- --- ---
Sub2API An open-source gateway that turns access to AI subscription accounts and upstream API keys into an API for its users. It handles authentication, routing, and billing. Itsmonitoring code checks whether upstream models answer. 2,421 prompt requests carried the label;320 returned HTTP success. Some short checks were roughly five minutes apart. We haven’t identified the deployment sending them.
keypool Key pooling means managing multiple API keys through one program or gateway. Public projects such as llm-keypool do this. We found no verified code match for the software sending these requests. 1,060 labelled prompt requests;823 returned HTTP success. Alongside short checks, requests carrying this label included therecurring collector description .
Zoltraak We couldn’t identify the software behind this label. A separate gateway operator also reported a ZOLTRAAK header while investigating an exposed AI gateway. 675 labelled prompt requests;410 returned HTTP success. These included short checks and prompts asking for a value that changed with each request.

Daily activity

How leaked-key use changed over time #

We tracked the keys we leaked on GitHub to see how they were used. The chart shows all 11,841 requests using those keys: model-list checks, prompts, and failed attempts.

Operator takeaways

What to look for in your own gateway logs #

The examples give us three patterns to investigate when grouping gateway requests by credential:

  1. Many model names requested through the same key in a short window.
  2. Repeated checks at a stable interval after a key has already worked.
  3. A change in the addresses using a key, especially during a burst of prompt requests.

Compare these patterns with your own SDKs, load balancing, and monitoring before treating them as abuse. A stable identifier lets you group requests without storing the raw key. We haven’t measured detection accuracy or false positives.

Methods

How we counted and linked the requests #

Scope. Aggregate counts use the October 11 snapshot and only keys backed by our publication records. Known owner traffic, including our Israel and Westfield addresses, is excluded. The eight-address test comes from a separate 24-hour capture ending October 12; its counts are not added to the frozen totals.

Capture. Response recording started partway through the study. HTTP success comes from request metadata and does not establish answer quality. Older captures could truncate long text.

Attribution. Headers and conversation histories are supplied by the requester. A DNS match corroborates a recorded address, not a person. Older logs did not separately retain socket peers, so forwarded addresses cannot all be independently verified.

Labels. Coding and agent categories use lexical indicators in the latest user message. Embedded instructions, tool results, and Telegram fields are submitted context, not independently authenticated activity.

Exposure. Keys were published in waves and had different amounts of time to be found. New York and San Francisco also had different observation windows and API surfaces. The totals describe this experiment, not a geographic comparison or a general leak rate.

InferTrail

Seeing similar patterns in your gateway logs? #

I’m happy to compare notes on what you’re seeing and which signals are available in your gateway metadata.

── more in #ai-safety 4 stories · sorted by recency
── more on @litellm 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/we-tracked-ai-key-th…] indexed:0 read:26min 2026-11-12 · —