Blog

How to Rotate API Keys After a Breach Without Downtime (A Runbook)

Railway's preliminary report confirms that at most 1.85% of workspaces had environment variables potentially exposed. Here's what Railway confirmed, and how I rotate keys with an overlap window so nothing goes down.

Caleb Dorris 22 October 2026, 12:05 PM Updated 2 November 2026 28 min

Cover reading "Rotate Your API Keys" with a Security runbook tag: a hand adding a new key to a ring of old keys on a dark workbench, with discarded keys beside it.

Updated November 2, 2026, with Northflank's October 30 breach and what it told customers to rotate. Updated October 28, 2026, with a section on vendor breaches and third-party scripts after the Amplitude incident. Updated October 24, 2026, with Railway's preliminary incident report, a no-downtime rotation order and an audit-log checklist.

Knowing how to rotate API keys used to be a once-a-year chore. This week it's urgent for a lot of people. On October 21, Railway said an unauthorized party may have accessed customers' encrypted environment variables and decrypted some of them. The same morning, a poisoned LiteLLM 1.107.0 was published to PyPI and Docker with a credential stealer inside.

Different incidents, same job: assume the secrets are gone, replace them without taking the app down, and make sure the old ones stop working. This post is the runbook. If you want the prevention side for PHP dependencies, that's in my Composer supply chain checklist.

Breach notice in your inbox and no time for a runbook? Get a free quote and I'll help you work through it.

Update, November 2, 2026

Your host got breached again: Northflank says rotate every environment variable

Nine days after Railway disclosed its incident, it happened to another hosting platform. On October 30, Northflank's status page told customers to "Assume all environment variables have been decrypted. Disable/rotate all keys." Its timeline starts with a threat alert from Wiz at 6:43 AM CDT. The first "rotate environment variables immediately" notice went up at 8:40 AM CDT, and by 10:12 AM CDT Northflank said multiple users were confirming their AI keys had been used.

The awkward bit: on October 22, Northflank published a guide to migrating off Railway. It now carries a note that Northflank "experienced a similar attack". I'm not dunking on them, it could have been anyone this month. Wiz's "Black October" write-up counts at least nine AI developer platforms that disclosed incidents in October, Railway and Northflank included, and says the attacks went hunting for stored environment variables, especially ones that unlock AI models. So switching hosts isn't a security plan on its own. Knowing how to rotate fast is.

Where it stands now. In its November 2 update (5:09 AM CST), Northflank said it believes the attack vector was contained within an hour of the first alert, that it has seen no sign the attacker was in its environment after the attack, and that independent forensic auditors are reviewing it. It says running workloads were unaffected, it has seen no sign that workloads or workload data were accessed, and the evidence suggests the attack "was focused on secrets held in our control plane." Customers on forward-deployed or dedicated control planes are unaffected. It hasn't said how the attacker got in or how many customers were affected, and it says it will share a root cause analysis once findings are confirmed.

If you're on Northflank, here's what it says to do (as of that November 2 update):

  1. Rotate every secret, not a sample, "even if you haven't seen suspicious activity." That means integration secrets and project secrets, including secrets on workloads, secret groups and global secrets. Revoke each key with the provider that issued it, create a new one, then update Northflank and redeploy. Deleting the variable in Northflank doesn't kill the key.
  2. Go in this order. Northflank recommends starting with AI provider keys, then cloud provider credentials, payment provider keys, private keys, and database and other service credentials. Some customers have reported unauthorized use of their AI keys.
  3. Rotate database and add-on credentials. Secret rotation is now available for Postgres, MongoDB, MySQL, Redis, MinIO and RabbitMQ add-ons. Turn off public access on add-ons unless you really need it.
  4. Sign in again and reconnect your integrations. Where it could, Northflank revoked its access tokens and sessions, VCS integrations, and cross-account IAM roles and service accounts.
  5. Check your provider logs and AI usage and billing for anything you didn't run, contact the AI provider directly if you see unexpected spend, and read the audit logs Northflank turned on for every customer, free accounts included.

That order matches what I'd do anyway: AI keys first, since those are the ones being used, then everything else using the list below.

Update: what Railway's preliminary report confirmed

On October 22, Railway published a preliminary report on the incident. Here's what it confirms, in Railway's own terms:

  • Scope. Railway says at most 1.85% of all workspaces had some environment variables potentially compromised, about 100,000 workspaces. It's reaching out to customers with definite impact, plus a larger group it considers high risk.
  • What the attacker wanted. Railway says the attacker appeared to be after AI provider and platform API keys. It sees two higher-risk groups: workspaces with a very large number of environment variables, and environments with a lot of AI vendor keys.
  • What wasn't touched. Railway says individual user accounts weren't logged into and running services stayed online the whole time. It isn't ruling out access to user source code yet and says it will confirm in its final report.
  • The window. Railway puts the attack between 8:58 AM CDT on October 20 and 10:32 PM CDT on October 21 (13:58 UTC October 20 to 03:32 UTC October 22).
  • Vendor revocations. Railway worked with GitHub, GitLab, Anthropic, OpenAI, OpenRouter, SpaceXSI, Stripe and others to revoke potentially exposed keys. For some vendors it sent every key stored on the platform. Railway says a revocation email from a vendor doesn't by itself mean your key was exposed.
  • What Railway reset. Railway revoked all Railway access tokens and rolled every GitHub App installation. If your GitHub email differs from your Railway email, you may need to log in with "Log in using email."

What Railway tells customers to do: if you signed up before October 21, rotate the sensitive variables and keys you store on Railway. Remove public network access to your databases. Check your GitHub audit log and review every app with access. Check the audit logs in your container registries, such as Docker Hub.

A vendor revoking a key for you isn't the same as you rotating it. If a provider killed your old key, your app may already be failing. Generate a new one, deploy it, and then work through the rest of this list.

Did the Railway breach or LiteLLM 1.107.0 affect me?

Railway. If you keep environment variables in Railway, Railway recommends that every user roll all of them as a precaution, including API keys and private registry credentials, and review logs for unusual activity. It says it will email the customers it confirms were affected, but don't wait for that email. Railway also reset two things for you: the S3 credentials for every storage bucket and the GitHub tokens it held. Your services need a redeploy to pick up the new bucket keys, and you have to reconnect GitHub yourself. GitHub tokens that were stored as registry credentials keep working on GitHub until you revoke them there. Railway paused deployments during the investigation, so check its status page before you plan a redeploy.

LiteLLM. You're affected if you ran an unpinned pip install between 11:39 and 13:23 UTC on October 21 (6:39 to 8:23 AM Central). Docker counts too, if you started the v1.107.0, latest, main-latest or main-stable images between 11:46 and 14:20 UTC (6:46 to 9:20 AM Central). The payload ran every time Python started, even if nothing imported LiteLLM. It went after cloud credentials, SSH keys, environment variables, AI tool configs and the provider keys stored in the LiteLLM proxy's database.

For LiteLLM, clean up before you rotate. LiteLLM says not to start with pip, because any Python start runs the payload again. Delete cook.pth, cook.py and sitecustomize.py from site-packages, kill the background Python process, then rebuild from scratch pinned to litellm==1.106.2. Rotating keys on a box that's still infected just hands over the new keys.

What about the Capcom ID breach?

Not every breach this week is about your keys. On October 22, Capcom disclosed unauthorized access to CAPCOM ID affecting 11,774,247 accounts. Email addresses, login timestamps and last-login IP addresses were exposed, and 43 of those records also included birth date, gender, country and nickname. Capcom says it found no compromise of user-set passwords, but someone changed the passwords on 196 accounts, which have since been reset. No credit card data was involved.

The bigger risk now is phishing that pretends to be Capcom. If your work email is tied to a gaming account like this, expect convincing fake "reset your password" emails, and never rotate a key from a link in one.

What about vendor breaches like Coinbase and Amplitude?

On October 28, Coinbase said a security incident at Amplitude, an analytics vendor, "impacted a small subset of Coinbase customer contact data, among other Amplitude customers." In Coinbase Support's statement, the company says it found no evidence of unauthorized access to its own systems, customer funds weren't affected, and it's notifying affected customers and regulators. It hasn't said how many people were affected, which fields were exposed, or when it happened. A figure of more than 70,000 users is going around on X, but Coinbase hasn't confirmed it. When I wrote this, I couldn't find a public statement from Amplitude.

The same day, three South Korean financial firms reported breaches. Daishin Securities said personal and credit information for 38,490 customers leaked from a server tied to opening investment accounts online. The data included names, email and postal addresses, and encrypted account and mobile phone numbers. The crypto exchange Bithumb said an outsider got into its internal employee messaging and work app and took personal information. It says that app is separate from trading and is still checking whether member data was involved, though Yonhap, citing an industry source, reports that some customer information leaked. The asset manager Mirae Asset Global Investments said an outside IP address viewed some internal business systems, including some employees' names, and that investor data wasn't leaked.

The Coinbase case is the one most small businesses should learn from, because your customers' data doesn't only live in your own systems. Every analytics tag, chat widget, payment SDK and CRM integration you add holds either a token or a copy of that data. Here's how I handle that side of things:

  1. Inventory every third-party script and SDK. Check your tag manager, your page source, your WordPress plugins, package.json and composer.json, and any mobile app SDKs. For each one, write down the vendor, what it collects and who owns the account.
  2. Scope and rotate vendor tokens. Give each vendor its own key with the narrowest permissions it offers, such as read-only access, one project or an IP allowlist. When a vendor reports an incident, rotate the keys you gave it and any keys it uses to call your systems, using the same no-downtime order above.
  3. Send analytics less. Don't send email addresses, phone numbers or names as event properties or user IDs. Use an internal ID instead. Turn on IP and PII masking where the tool supports it, and stop collecting fields you never look at.
  4. Review vendor access. List the OAuth apps connected to Google Workspace or Microsoft 365, GitHub, Slack and your CRM. Remove old vendors and integrations you no longer use, and make sure vendor accounts use SSO or MFA.
  5. Get ahead of the phishing. Leaked contact data is what phishing runs on. Tell your customers how you'll actually contact them, and that you'll never ask for a password, a one-time code or a payment from a link.

If you're not sure which scripts and vendors touch your customer data, get a free quote and I'll help you map them and lock down the tokens.

Update, October 29, 2026

Polymarket: when a performance-monitoring script turns into a wallet drainer

On October 29, Polymarket stopped trading on its international site for about an hour. In its status update, Polymarket said "one of our third party providers was compromised," that it had fixed the issue and referred it to law enforcement, and that "anyone who has been impacted will be made whole." Polymarket hasn't named the vendor. Around the same time, DebugBear posted that it was "impacted by an ongoing security incident" and told customers of its real user monitoring (RUM) product to remove its embed code from their sites. DebugBear is a website performance-monitoring company. CNBC reported, citing a person familiar with the matter, that Polymarket's problem came from the DebugBear hack. Two analytics firms told CNBC that one account withdrew at least $2.7 million across 710 wallets. Polymarket hasn't confirmed a total.

Hudson Rock's analysis of the script found it didn't need passwords or private keys. It waited for a logged-in user, found the trading client already running in the page and tried to use it to sell positions and send the funds to another address. Hudson Rock also found a Polymarket build that removed the DebugBear script that same day. It's the same trick as TRUST#GRAFT: borrow a session the user already opened.

A third-party script runs with the same power as your own code. It can read the page, read browser storage and do anything the logged-in user can do. On top of the inventory above, I'd add:

  • Keep vendor scripts off sensitive pages. Analytics and monitoring tags rarely need to run on login, checkout, account or admin pages.
  • Pin what you can. For a fixed file, add Subresource Integrity (an integrity hash) so the browser refuses a changed copy, or host the file yourself so it only changes when you deploy. Scripts a vendor updates on its own can't be pinned this way. Treat those as the riskiest ones on the list.
  • Set a Content Security Policy. Limit where scripts load from and where the page can send data. It won't stop a bad file from a domain you already allow. Hudson Rock notes Polymarket's policy allowed the script's host. Still, it shrinks what a compromised script can reach.
  • Know how to pull a tag in minutes. DebugBear's advice was to remove the embed code. Make sure you know which file, tag manager or plugin controls each one, and who can change it.

Update, October 31, 2026

DNS hijacks: when attackers swap out your whole site, not just one script

Two days after Polymarket, the same kind of attack moved up a level. Late on October 30, Blockaid flagged flap.sh and kintsu.xyz, then named ten more DeFi sites it said were "actively serving the Step Drainer," a wallet-draining kit. Flap said its domain was "affected by a DNS hijacking incident" and redirecting to an unauthorized website. Kintsu said it was "a DNS hijack at our registrar". Kintsu said its domain was registered through Vercel Domains. In its October 31 update, Kintsu said an "unauthorized nameserver change at our domain registrar" sent visitors to a malicious clone of its site from about 7:15 to 11:11 PM CDT on October 30, with some networks still showing the clone until about 12:20 AM, and that its frontend code and smart contracts were not compromised. Kintsu names that registrar as Vercel, which it says uses Name.com. That's Kintsu's account. Vercel hasn't published a statement that I've seen, Kintsu says it's still investigating the cause with its providers, and nobody has published a loss total. Flap and Kintsu were both back up by early October 31.

Here's why this one is different. With Polymarket, one bad script ran inside the real site. With a DNS hijack, your code, servers and API keys can all be fine, and visitors still land on the attacker's page at your address. Rotating keys doesn't fix that. The account that controls your domain is the key that matters.

Protect your DNS and frontend:

  • Lock the domain. Ask your registrar to set the locks in ICANN's status code guide: clientTransferProhibited, clientUpdateProhibited and clientDeleteProhibited. For a domain your business can't lose, ask whether the registry offers a Registry Lock service. ICANN notes removing a registry-level lock takes longer because your registrar has to go through the registry. That delay is the point.
  • Put strong 2FA on every account that can change DNS. That means the registrar, your DNS host and the hosting account if it manages your domain. CISA's DNS tampering directive told federal agencies to change those passwords and add MFA, and says SMS codes aren't recommended. Use an authenticator app or a security key, and keep the list of people with access short.
  • Add CAA records. A CAA record lists which certificate authorities may issue certificates for your domain (Cloudflare's guide shows the setup). It's cheap and blocks some mis-issuance. It won't stop someone who already controls your registrar account, because they can change your nameservers and your CAA records with them.
  • Turn on DNSSEC where your setup supports it. DNSSEC signs your DNS answers so resolvers can spot forged ones (Cloudflare's DNSSEC docs). It has the same limit as CAA: it protects against forged answers, not against someone logged in as you. Not every provider supports it. Vercel staff said in its community forum this year that DNSSEC isn't supported for domains on Vercel's nameservers or bought through Vercel Domains.
  • Watch for changes. Turn on change alerts at your registrar and DNS host if they offer them. Check crt.sh for certificates you didn't request. CISA's directive has agencies monitor those Certificate Transparency logs. A new certificate for your domain that you didn't ask for is a loud warning.
  • Have a way to warn people that doesn't depend on the domain. Kintsu and Flap both warned users on X while their sites were down, and Flap pointed people to a backup domain. While trying to reach its registrar, Kintsu said "support is a bot." Know your registrar's security contact and your escalation path before you need them.

If you connected a wallet or signed anything on one of the sites Blockaid named during the window, follow that project's own instructions. For Kintsu, that means moving your funds to a new wallet: it says the attack used a wallet "delegation" signature, "so revoking token approvals alone is not enough." Facts as of about 9:50 AM CST, November 2.

Update, November 2, 2026

BTCPay Server hot wallets were swept on servers still on 2.4.1 or older. If that's you, rebuild, don't just update

At 4:25 PM CST on November 1, BTCPay Server, the free self-hosted Bitcoin payment processor, posted on X that hot wallets on BTCPay servers were "being swept by unauthorized attackers" and told everyone running it to shut down with ./btcpay-down.sh.

Late that night BTCPay narrowed it to servers on 2.4.1 or older, and on the morning of November 2 it published its security advisory. Per BTCPay, the attacks "targeted servers running BTCPay Server 2.4.1 (released on 23 July 2026) or earlier," and "the attackers used a different method to exploit the vulnerability fixed in 2.4.2," which came out August 7. BTCPay says it has "seen no impact from these attacks" on servers that were already on 2.4.2 or later when it sent the warning. The first drain in the reports it received happened at 7:46 AM CST on November 1, more than eight hours before the alert, and BTCPay says it hasn't established when attackers first started. Lead developer Nicolas Dorier said the attacker logged in as admin, and BTCPay developer Andrew Camilleri says the attacker is scanning the internet for BTCPay servers and trying to break in in batches. For context, 2.4.2 fixed several security problems, including a critical one attackers were already using in August to steal Lightning (LND) credentials, as BTCPay's August advisory explained, and a two-factor login bypass. The new advisory doesn't publish the technical details of how the hole was used this time.

How much was taken: BTCPay hasn't published a number, and it warns that the balances of the two destination addresses "should not be treated as a confirmed total of losses," because some activity there appears to predate the reported thefts. Bitquery, a blockchain analytics company, traced about $1.63 million (18.38 BTC and 3,405 LTC) in 682 sweeps to those addresses between October 30 and November 2 and calls that a floor. Its count starts before the first theft in BTCPay's reports, which is the kind of overlap BTCPay is cautioning about. Treat both as rough until BTCPay says more.

Why this matters even if you never touch Bitcoin: the fix shipped in August. The servers that got emptied were the ones that never took it. BTCPay's advisory says it outright: "With the rise in automated attacks using AI, we ask all users to be diligent about installing BTCPay Server updates as they are released." And a hot wallet is a private key sitting on a server that faces the internet. BTCPay's own wallet setup guide says a hot wallet "is convenient but exposes funds if either the account or server is compromised." Per the advisory, funds in wallets whose spending keys are held off the server, including hardware wallets, weren't affected. Same lesson as the boxes above.

If you run BTCPay Server:

  1. Check your version first. Log in and look at the bottom of the page. If you can't check right now, shut it down the way BTCPay said: on a standard Docker install, SSH in, run sudo su -, then cd btcpayserver-docker and ./btcpay-down.sh (the script just stops the containers). While it's off, switch off the Bitcoin payment option in your store so customers don't get stuck.
  2. On 2.4.1 or older, or you updated from one after the November 1 warning: move to a fresh server. BTCPay recommends this even if you haven't noticed a theft, and even if your wallet keys live elsewhere. Camilleri put it plainly: "updating after the fact is not enough. Treat the entire machine as compromised." BTCPay's steps: sweep whatever is left in the hot wallet to a new wallet with a new seed, made on a trusted device (reusing the old seed on a new server leaves the funds at risk). Take the old server offline and keep its logs and transaction records. Build a fresh VM with the latest release from trusted sources, connect the new wallet, and don't restore the whole old server onto it. Then, from a trusted device, replace every credential the old server could reach: hosting, SSH, application, API and Lightning. Don't type new credentials on the old machine. For a store, that includes the API keys and webhook secrets your shop and connected apps use. If you lost funds, email security@btcpayserver.org with your version, when you noticed, and the transaction IDs and addresses. Never send seed phrases, keys or passwords, and BTCPay says to report a theft to your local authorities too.
  3. Already on 2.4.2 or later when the warning went out: BTCPay has seen no impact on those servers. Update to 2.4.7 (October 29), the current release, which fixed 85 findings from Anthropic's OSS scanner, one rated critical. On a standard install that's Server Settings, then Maintenance, then Update.
  4. If a host runs it for you, BTCPay says LunaNode and other hosting providers took instances offline as a precaution. If yours was on 2.4.1 or older, BTCPay says to ask your provider for help moving to a fresh VM.
  5. Keep the hot wallet small, or go watch-only. BTCPay's advice: if you need a hot wallet for daily operations, keep only what those operations need on the server and move the rest to a wallet whose spending keys are held elsewhere. Dorier, the night of the attack: "Don't put more than you are ready to lose in hot wallet." BTCPay's guide says connecting an existing wallet by its public data (the xpub) "keeps private keys off the server," so a break-in can't spend your coins. Check receiving addresses on your hardware wallet's screen, since an admin can still change where future payments go.
  6. Watch the official channels, not screenshots. Follow @BtcpayServer on X, the BTCPay blog and the GitHub releases page. Incidents like this bring out fake "fixes." Don't install anything from a DM or a reply link.

Facts as of about 9:40 AM CST, November 2. BTCPay's advisory is the source of record, and I'll update this if it changes.

How do I rotate API keys without downtime?

The trick is never having a moment where the only valid key is the old one, or where the app only knows the new one before the provider accepts it. I call it a dual-accept window: for a short time, both keys work. Here's the order I work in.

  1. List every secret the system could read. That means environment variables, .env files, CI secrets, registry credentials, cloud roles, database passwords, OAuth client secrets, webhook signing secrets, SSH keys and AI provider keys. If a process on that host could read it, it goes on the list.
  2. Rank by damage. Cloud and admin credentials come first, then anything that leads to more secrets (GitHub tokens, registry logins), then databases, then anything that moves money or sends email and texts as you. AI provider keys can run up a bill fast, so they come right after.
  3. Create the new key next to the old one. Most providers let two keys be active at once, or let you set the old key to expire later. Check your provider's docs before you start. If a provider only allows one key, plan a short maintenance window for that one.
  4. Store the new value in one place. Update the shared variable or secret manager, not five pasted copies.
  5. Redeploy everything that reads it. Containers read environment variables at startup, so a new value does nothing until each service restarts. Go one service at a time, and watch error rates after each.
  6. Confirm traffic is on the new key. Most provider dashboards show when each key was last used. When the old key's "last used" time stops moving, you're ready.
  7. Revoke the old key today. Not "once things settle down." An old key that still works is the whole problem.
  8. Prove it's dead. Make one request with the old key and expect a 401 or 403. I don't count a key as rotated until I've seen that.

Which secrets should I rotate first?

Start with anything that leads to more secrets. A cloud role or a GitHub token can read other credentials, so an attacker with one gets the rest. After that, rotate the database password, because it's the one that leads straight to customer data.

Secrets that need their own overlap

Some secrets aren't a simple swap.

  • Database passwords. Create a new database user or password, point the app at it, redeploy, then drop the old login. If you change the password in place, every running copy of the app fails until it restarts.
  • Webhook signing secrets. The sender signs with the secret and your app verifies it. Have your app accept both the old and new secret during the switch, then flip the sender, then remove the old one from your code.
  • JWT signing keys. Publish the new public key first, then start signing with the new private key. Keep the old public key around until every token signed with it has expired. A kid (key ID) header makes this painless.
  • OAuth client secrets. Some providers let you add a second client secret before you delete the first. Others don't, so check before you start.
  • Registry and deploy tokens. Railway notes that GitHub tokens stored as registry credentials keep working on GitHub until you revoke them on GitHub.

Where do old keys hide?

The key you forget is the one that gets used. These are the usual places:

  • A pasted copy in a second service instead of a shared reference. Railway's own guide calls this out.
  • A local .env on your laptop, or a teammate's.
  • CI variables and deploy scripts.
  • A cron job on a different server that nobody remembers setting up.
  • AI coding tools. The LiteLLM stealer specifically went after editor and agent config folders, including ~/.cursor.

Check the audit logs for the exposure window

Rotation stops the next use of a key. It doesn't tell you whether someone already used it. For the window your host says was exposed, check:

  • GitHub: your account and organization audit logs, plus the list of authorized OAuth and GitHub Apps. Railway calls this out specifically.
  • Container registries: Docker Hub or whichever registry you use. Look for pushes or pulls you don't recognize.
  • Cloud accounts: audit trails for logins, new keys or new users you didn't create.
  • AI providers: usage dashboards for spikes, unfamiliar models or traffic at odd hours.
  • Payment and messaging providers: API request logs for anything you didn't send.

Write down what you rotated, when, and what the logs showed. If a client or your insurer asks later, you'll want that record.

The caveats

Rotation can't un-leak data. If the stealer had the database password, the data may already be gone. Rotation stops the next use.

Short outages happen. Even with overlap, some service will be holding the old value. Do it in a quiet window if you have the luxury, but don't wait days for one.

Your vendor's revocation isn't your revocation. Railway says it told upstream AI providers to revoke keys proactively. Check yours anyway.

The work is tedious, and that's the point. Every step you skip is a key that still works for someone else.

What I do differently now

Each secret lives in one place per environment, and everything else points to it. Each environment gets its own keys, so a staging leak doesn't touch production. AI keys get spending limits where the provider supports them. Agents get the narrowest access I can give them, the same rule I use in my AI coding setup. If you moved a Salesforce integration to OAuth, like I covered in the SOAP login() retirement post, the client secret goes on the list too.

Most of the integrations I build connect two or three outside services, so each one comes with its own rotation plan. You can see what that work looks like on my integrations page.

Need a hand?

Need keys rotated without breaking your integrations?

Rotating one key is easy. Rotating every key an app could read, in the right order, without taking the app down, is tedious, and the key you forget is the one that gets used. I'm a little obsessive about the "prove it's dead" step, which is exactly what you want here.

How I handle it:

  1. List and rank every secret. Environment variables, CI secrets, database passwords, OAuth and webhook secrets, AI provider keys, and the cron job on the server nobody remembers.
  2. Rotate with an overlap window. The new key goes in next to the old one, lives in one place, and gets redeployed service by service. Then the old key is revoked and tested to confirm it fails.
  3. Check the logs and write it down. GitHub, registry, cloud and provider logs for the exposure window, and a record of what changed and when.

The aim is no downtime, but I won't promise it. Some providers only allow one active key at a time, and those need a short maintenance window. I'll tell you which ones before we start. If a breach notice landed in your inbox and you're not sure what your app exposes, get a free quote.

Caleb Dorris, senior software developer in Nashville

FAQ

How do I rotate API keys safely?

Create the new key, update it where the secret is stored, redeploy every service that reads it, then revoke the old key. Finish by making one request with the old key to confirm it now fails.

Do I need to rotate keys if Railway didn't email me?

Railway recommends that all users roll every environment variable stored in Railway as a precaution. Its email goes to customers it has confirmed were affected, but the precaution applies to everyone.

Is LiteLLM safe to use now?

LiteLLM says only 1.107.0 was compromised, and it has been pulled from PyPI, Docker Hub and GHCR. It recommends pinning litellm==1.106.2 or another explicit earlier version, and rebuilding any environment that ever ran 1.107.0.

What's the difference between rotating and revoking a key?

Rotating replaces a key with a new one. Revoking makes the old key stop working. A rotation isn't finished until the old key is revoked.

Can I rotate API keys without downtime?

Usually, yes. Create the new key while the old one still works, deploy it everywhere, confirm traffic has moved, then revoke the old key. The only real downtime risk is a provider that allows just one active key at a time.

How many Railway workspaces were affected?

Railway's preliminary report says at most 1.85% of all workspaces, about 100,000, had some environment variables potentially compromised. Railway still recommends that everyone who signed up before October 21 rotate the sensitive variables they stored there.

A vendor revoked my key. Was my key leaked?

Not necessarily. Railway says it sent some vendors every key it stored, regardless of whether those keys were known to be affected, so a revocation notice alone doesn't mean your key was exposed. Replace the key either way, because the old one won't work anymore.

Do I need to rotate keys if one of my vendors was breached?

Rotate any keys you gave that vendor and any keys it uses to reach your systems, even if the vendor says only contact data leaked. If customer contact details were exposed, the bigger risk is phishing, so warn your customers about it too.

I'm on Northflank. Do I need to rotate my environment variables?

Yes. Northflank told every customer to assume all environment variables were decrypted and to rotate all of them, including secrets on workloads, secret groups and global secrets, even if you haven't seen anything suspicious. Start with AI provider keys, then cloud, payment and database credentials. Revoke each old key with the company that issued it, not just in Northflank, sign in again to reconnect your integrations, then check your AI usage and billing for calls you didn't make.

Sources

Need a web developer in Nashville?

PHP, WordPress and Next.js. Free quote, and I usually reply within a couple of hours.

caleb@calebdorris.com and call or text (615) 914-1073

All posts