On 30 October 2026 Northflank told every customer to assume all environment variables were decrypted and to disable or rotate every key stored on the platform. Within hours, users reported that AI API keys held there had been used by someone else (Northflank status page). It is the ninth AI developer platform to disclose an incident this month, according to Wiz's "Black October" report, and the pattern is the same each time: the attacker wants the environment variables, and above all the ones that buy model inference.
This article is for engineers who deploy on Northflank, Railway or any platform that stores your secrets for you. It covers what is known about the Northflank incident, why stolen AI keys are worth so much, the order to rotate things in without taking production down, how to check AWS Bedrock for abuse with CloudTrail, and how to scope a key so the next leak costs less.
What happened in the Northflank breach?
A Wiz threat alert fired at 11:43 UTC on 30 October; by 13:58 Northflank had moved the incident to Identified and told customers to treat every environment variable as exposed. The root cause has not been published. Networking, services, builds, jobs, add-ons, certificates and logs were all marked as a major outage while the team patched (status page).
| Time (UTC) | What happened |
|---|---|
| 30 Oct 11:43 | Wiz threat alert triggered; engineers reviewing within a minute |
| 30 Oct 12:02–13:05 | Network policy patch, then two further patches; Wiz CIRT support requested at 13:00 |
| 30 Oct 13:40 | Customers told to rotate environment variables immediately |
| 30 Oct 13:58 | Status Identified: assume all environment variables decrypted; disable or rotate all keys |
| 30 Oct 15:12 | Secret rotation for Postgres and MongoDB enabled for all users; users confirm AI keys were used |
| 30 Oct 23:38 | More reports of unauthorised use of AI API keys stored on the platform |
| 31 Oct 01:04 | Audit logs enabled for every customer, free tier included |
| 31 Oct 13:34 | Secret rotation for MySQL and Redis made available |
Two things in that timeline matter more than the rest. First, the instruction covers every secret — workload variables, secret groups and global secrets — not only the ones you think of as sensitive. Second, the abuse was visible within hours, which means the window between theft and use is short. Northflank has not said how the variables were decrypted, and the Hacker News thread has no statement from staff, so treat any root-cause theory you read elsewhere as unconfirmed.
Why do attackers target AI API keys on developer platforms?
Because a working inference key can be resold the same day. Wiz calls it LLMJacking: stealing access to large language models and reselling it. Its report lists nine platforms that disclosed incidents in October — Fireworks AI, Andromeda, Zeabur, Lightning AI, OpenCode, Railway, Warp, CommandCode and Northflank — and notes that every public report describes "targeted hunting of stored environment variables, especially those granting AI access" (Wiz).
Railway's own disclosure says the same from the victim's side: it detected anomalous activity in "systems that store customer environment variables" on 21 October, some decrypted values may have been taken, and it believes the attack is part of a series "targeting platform companies" to compromise AI inference providers (Railway).
- PaaS secret store → Initial theft
- Initial theft → Validation sweep
- Validation sweep → Key checker
- Key checker → Reseller pool
- Reseller pool → Bulk inference
- Bulk inference → Your cloud bill
Wiz followed two enterprise AWS keys that leaked through vendor breaches. In both, the first unauthorised InvokeModel call came within 30 minutes of the reported credential access, from a residential IP sweeping several organisations in one minute. For days afterwards each key saw 14–120 calls a day from one small Go client — a checker making sure the key still worked. Then the bulk traffic arrived (Wiz).
Source: [Wiz, Black October for AI developer platforms](https://www.wiz.io/blog/black-october-for-ai-developer-platforms)
| Approximate calls | |
|---|---|
| Case A (unrestricted) | 800k calls |
| Case B (us.* only) | 1.7M calls |
The restricted key in Case B still produced more than a million successful calls; most of its other traffic was throttled by regional quotas. Wiz estimates the two cases "likely ran up over $100k in usage" at list price, and the traffic looked like resold coding-agent sessions: heavy prompt caching and a long tail of large uncached inputs (Wiz). Scoping a key limits what it can reach. It does not stop a determined reseller from spending your quota.
What to rotate first after the Northflank breach, and in what order
Rotate what can be turned into money fastest, then what gives access to data, then everything else. Revoking at the issuer is what counts; changing the value in Northflank alone leaves the stolen copy working.
- AI provider and cloud keys first. OpenAI, Anthropic, Google, AWS and any inference reseller keys. Revoke them with the provider, create replacements, then update the secret in Northflank. Then check usage and billing for the last few days (see the next section).
- Database credentials second. Northflank now offers rotation for Postgres and MongoDB (since 30 October) and MySQL and Redis (since 31 October). If you enabled public access on an add-on, turn it off (status page).
- Payment, email and webhook secrets third. Stripe keys, SMTP passwords, webhook signing secrets, OAuth client secrets.
- Build and source credentials. Registry tokens, Git deploy keys and CI tokens stored as variables or secret groups.
- Everything else. Session-signing keys, encryption keys and internal service tokens. Rotating a session secret logs every user out, so schedule it, but do it.
What breaks when you rotate in a hurry is usually the order of operations. If you revoke a database password before the new one is in every service, connections fail as pools recycle. For anything that supports two live credentials — an IAM user can hold two access keys, and AI providers generally let you create several API keys — create the new key, deploy it, confirm traffic has moved, then revoke the old one. For a single-password resource, rotate during a short window and restart the services that hold connections. The one exception is a key you can see being abused: revoke that immediately and accept the outage.
Northflank switched on audit logs for every customer on 31 October. Use them to see what changed in your team since the incident: they record the event type, who or what triggered it, the source and, for configuration changes, the before-and-after template. Audit log sinks can forward events to S3, but new sinks do not export earlier events, so read the UI now rather than waiting for a sink.
How to check whether a stolen key was used on AWS Bedrock
Look in CloudTrail. Bedrock logs InvokeModel, InvokeModelWithResponseStream, Converse and ConverseStream as management events, which CloudTrail records by default, so you have a history even if you never set up data events (AWS docs). Filter by the access key that was stored on the platform.
# The access key ID that was stored in Northflank (not the secret)KEY=AKIAEXAMPLEEXAMPLE aws cloudtrail lookup-events \ --region us-east-1 \ --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=$KEY \ --start-time 2026-10-29T00:00:00Z \ --query 'Events[?EventSource==`bedrock.amazonaws.com`].[EventTime,EventName]' \ --output tablelookup-events covers the last 90 days in one region at a time and returns pages of 50, so for a key used heavily it is quicker to count with a short script. This one groups calls by source IP and model, which is what you need to separate your own servers from someone else's:
import json, sysfrom collections import Counterfrom datetime import datetime, timezoneimport boto3 key_id, region = sys.argv[1], sys.argv[2]since = datetime(2026, 10, 29, tzinfo=timezone.utc) ct = boto3.client("cloudtrail", region_name=region)pages = ct.get_paginator("lookup_events").paginate( LookupAttributes=[{"AttributeKey": "AccessKeyId", "AttributeValue": key_id}], StartTime=since,) by_ip, by_model = Counter(), Counter()for page in pages: for ev in page["Events"]: if ev["EventSource"] != "bedrock.amazonaws.com": continue rec = json.loads(ev["CloudTrailEvent"]) if rec.get("eventType") != "AwsApiCall": # skip stream-completion events continue by_ip[rec.get("sourceIPAddress")] += 1 model = (rec.get("requestParameters") or {}).get("modelId", "?") by_model[model] += 1 print("calls by source IP:", by_ip.most_common(10))print("calls by model:", by_model.most_common(10))Run it as python bedrock_key_usage.py AKIA... us-east-1 for each region you use. The eventType filter matters: streaming calls also write a stream-completion record of type AwsServiceEvent, which AWS says to exclude when you count invocations (AWS docs). Calls from addresses that are not yours, sudden use of models you never call, or a burst of quota look-ups just before heavy traffic all match what Wiz saw. Wiz published four addresses seen checking or using stolen keys between 18 and 30 October — 23.106.46.239, 38.246.114.118, 104.243.32.50 and 31.57.201.201 — while noting they are not directly linked to the Black October intrusions (Wiz).
For OpenAI, Anthropic and other direct providers, the equivalent check is the usage page of the organisation or project the key belongs to, plus your billing alerts. If you find abuse, report it to the provider as well as to Northflank support, as the status page asks; providers can sometimes see more about where the traffic went than you can.
How to scope a Bedrock key so the next leak costs less
Give each workload its own credentials, allow only the models and inference profiles it uses, and deny global routing unless you need it. Wiz notes that Case A's policy allowed global.* cross-region inference profiles, so only about 6% of the abusive calls were throttled; Case B's key allowed only us.* profiles, and thousands of reseller requests for global.* failed (Wiz).
Global inference profiles have IDs starting with global.. AWS documents a detail that catches people out: when Bedrock evaluates the global foundation model, aws:RequestedRegion is unspecified, so a deny on a named region does not match it (AWS docs). The service control policy AWS gives for turning global routing off is:
{ "Effect": "Deny", "Action": "bedrock:*", "Resource": "*", "Condition": { "StringEquals": { "aws:RequestedRegion": "unspecified" }, "ArnLike": { "bedrock:InferenceProfileArn": "arn:aws:bedrock:*:*:inference-profile/global.*" } }}That is a fragment: put it inside the Statement array of an SCP with "Version": "2012-10-17", and attach it to the accounts that run your workloads. On the identity side, replace bedrock:InvokeModel on * with the specific inference-profile and foundation-model ARNs each service needs. A key that can only call one model in one geography is worth less to a reseller, and a key that fails on the first catalogue probe is more likely to be dropped from the pool.
Should AI keys live in platform environment variables at all?
Long-lived keys in a platform's secret store are convenient, and October showed their cost: when the store is breached, every tenant's keys go at once. You cannot remove that risk entirely on a managed platform, but you can make what is stored there less valuable.
Where the provider supports it, prefer short-lived credentials over static keys — on AWS, a role assumed through web identity federation rather than an IAM user's access key — so a stolen value expires on its own. Where you must store a static key, issue one per service and per environment, give it a spending limit at the provider if one exists, and keep a written list of where each key is stored. Knowing which secrets live on which platform is what turns a rotation like this one from guesswork into a list.
Commenters in the Hacker News discussion split between moving back to hyperscalers and self-hosting. Neither is automatically safer: Wiz's two enterprise cases were AWS keys leaked through vendors, not through AWS. The useful lesson is narrower — any place that can decrypt your secrets is part of your attack surface, and it should hold as few high-value secrets as you can manage.
The one thing to remember
If a platform tells you to assume your environment variables were decrypted, the stolen copies are already being tested. Revoke at the issuer, starting with whatever turns into inference spend, then check the provider's logs for calls you did not make — and scope the replacement key so that next time it is worth less to whoever takes it.
Questions people ask about the Northflank breach
Was Northflank hacked?
Yes. On 30 October 2026 Northflank opened a security incident after a Wiz threat alert and told all customers to assume every environment variable was decrypted. Users reported their AI API keys being used by others. The root cause has not been published (status page).
What should Northflank customers do after the breach?
Rotate every secret stored on the platform, revoking each key with its issuer rather than only changing it in Northflank. Start with AI provider and cloud keys, then database credentials, disable public access on add-ons, and check provider usage and billing for calls you did not make.
Does changing an environment variable in Northflank revoke the old key?
No. Updating the value only changes what your services use; the stolen copy keeps working until you revoke it at the provider that issued it, such as OpenAI, Anthropic or AWS IAM.
What is LLMJacking?
LLMJacking is stealing access to large language models, usually API keys or cloud credentials, and using or reselling that access. Wiz uses the term for the wave of October 2026 incidents in which attackers hunted AI keys stored on developer platforms (Wiz).
Which platforms were part of Black October?
Wiz lists Fireworks AI, Andromeda, Zeabur, Lightning AI, OpenCode, Railway, Warp, CommandCode and Northflank, all of which disclosed incidents in October 2026. Root causes differ and most are still under investigation (Wiz).
How do I see whether my AWS Bedrock key was abused?
Search CloudTrail for events from bedrock.amazonaws.com made with that access key ID. Bedrock logs InvokeModel and Converse calls as management events, which CloudTrail records by default (AWS docs).
Does restricting a Bedrock key to one region stop abuse?
It reduces it but does not stop it. In Wiz's Case B a key limited to us.* inference profiles still served more than a million successful calls in about 13 hours (Wiz).
Sources and further reading
- Northflank status page: security incident, 30–31 October 2026
- Wiz: Black October for AI developer platforms
- Railway: security disclosure, 21 October 2026
- AWS: Global cross-Region inference in Amazon Bedrock
- AWS: Logging Amazon Bedrock API calls with CloudTrail
- Northflank docs: audit logs
- Hacker News discussion of the Northflank breach
Discussion
Join the discussion
Sign in with Google, Apple or an email code to comment and reply.