Northflank is the ninth AI platform breach this month. Make a stolen AI key worth less. A developer at Voir Labs outlined a gateway design that limits the damage from stolen AI provider keys, after Wiz's "Black October for AI Developer Platforms" report documented incidents at nine platforms including Fireworks AI, Railway, Zeabur and Northflank. The design keeps the provider key inside a small self-operated gateway and issues each app its own token, with per-app model allowlists and hourly call ceilings; the author notes that scoping alone only delays abuse, citing one stolen Bedrock credential that made roughly 1.7 million calls in thirteen hours versus at most 120 a day normally. Originally published on voirlabs.io https://www.voirlabs.io/insights/stolen-ai-api-keys-platform-breaches?utm source=devto&utm medium=syndication&utm campaign=distribution by Moosa Jafri. An AI provider key stored as an environment variable on a hosting platform is only as safe as that platform, and in October nine of them disclosed incidents. The useful response is to plan for the next leak: make a stolen copy of your key able to do very little, and make its misuse loud within the first hour. This article walks through what attackers did with stolen keys, based on Wiz's investigation, and a small gateway design that limits the damage. On October 30, Wiz published "Black October for AI Developer Platforms", listing incidents at Fireworks AI, Andromeda, Zeabur, Lightning AI, OpenCode, Railway, Warp, CommandCode and Northflank. Its reading of the public reports: they "highlight targeted exploitation, explicitly hunting stored environment variables, with a focus on those granting AI access." It also says "there is no single vulnerability or dependency linking these attacks". The platforms' own words point the same way. Railway's October 21 disclosure says an unauthorized party "may have accessed encrypted environment variables and, for some of them, obtained the decrypted contents", and that it believes this "is part of a series of attacks recently targeting platform companies with the aim of compromising AI inference providers." BleepingComputer reported on October 20 that at Zeabur an attacker used "leaked internal credentials stored in plaintext" and stole "over 3.2 million environment variable records". On October 31 it reported Northflank's warning to customers: "Assume all environment variables have been decrypted. Disable/rotate all keys," followed by "Users have reported unauthorised use of AI API keys supplied to the Northflank platform". One label. Wiz has not confirmed that one group is behind all nine incidents, and Northflank has not said how attackers got in. Wiz traced two enterprise Amazon Bedrock credentials that had been stolen through vendor breaches. Its timeline is the most useful part of the report, because it shows when a defender could have noticed. Two numbers are worth putting side by side. By our arithmetic, 1.7 million calls in thirteen hours is about 36 calls a second; during the quiet period the same key made at most 120 a day. And the probe asked for models across several vendors in one sweep. If an app only ever calls one or two models, a request for any other model is a signal that arrives days before the bill. The second key in Wiz's report was scoped. Its policy allowed Bedrock "only through us. cross-region inference profiles", and the reseller pool that picked it up asked for global. profiles. For four hours, thousands of calls failed. Then a checker found the model IDs that worked, and the flood began. That's the honest lesson on scoping. A narrow policy cost the attacker time and produced thousands of failed calls that someone could have alerted on. It didn't stop the abuse, because the allowed path was still worth money. Scope is a delay and an alarm; a ceiling on volume is what limits the bill. Our approach for a team with several apps calling a model: the provider key lives only in a small gateway you operate, and each app gets its own token for that gateway. The app token is what sits in the hosting platform's environment variables. A sketch of how we would write the gateway's admission check, in TypeScript: type AppPolicy = { models: Set