top of page

AI Agent Security Failure Cost Me $4000 Because of An Exposed API Key

  • Jul 24
  • 9 min read
Iaroslav Belkin Lost 4000$ on AI Agent Security Failure Because of An Exposed API Key

Editorial note: This article is a first-person account combined with third-party verified reporting on the March 31, 2026 axios npm supply chain compromise, drawn from Wiz's own technical analysis, Huntress's incident writeup, Elastic Security Labs' malware analysis, Datadog Security Labs, and the maintainer's own public post-mortem on GitHub. No cloud provider, security vendor, or the axios project paid for placement or was informed of publication.




TL;DR



What Actually Happened to Me


This month I got an unusually large bill from Google.


What happened was really embarrassing and totally preventable. My project's Google API key is a public one by design. The kind that is in your frontend code, which is architecturally normal and expected. Somewhere along the way, someone on my team also enabled Gemini API access on the same project. Gemini API is paid, expensive, and heavily targeted. The internet runs continuous scanners probing public resources for exactly this combination. They found it. By the time Google's budget alert arrived, the damage was already done.


Google compensated roughly 75% after support negotiations. The rest came out of my pocket. An expensive lesson, and not an unusual one: if you search now, you will find a wave of LinkedIn posts from people with the same story.


But here is the part I want to talk about that gets much less attention.



The AI Agent Security Problem Nobody Is Naming


Here is the thing I actually want to talk about, because the Google bill is just the entry point.


Every time you ask an AI agent to do something real in the world, configure Cloudflare, SSH into a server, push to a repo, hit an external API, you hand it a credential. That credential goes somewhere. Chat history. An environment file. Project context. And from every one of those places it can walk out the door.


I used to paste API keys directly into chat windows. I know exactly how that sounds. The honest version: it felt completely natural because the workflow made it natural. Agent needs a key. I have the key. Done. I did not think of it as a security decision because it did not feel like one.


The problem is not only what you do with your own keys. Sometimes the threat arrives through a package you have been trusting for years, one your agent has no reason to question any more than you do.



The Package Everyone Trusted for Two Hours and Fifty-Four Minutes


On March 31, 2026, an attacker gained access to the npm account of jasonsaayman, the lead maintainer of axios, an HTTP client library with over 100 million weekly downloads, present in roughly 80% of cloud and code environments according to Wiz. Using that access, the attacker published two versions, 1.14.1 and 0.30.4, that added a single new dependency to the package: plain-crypto-js, a name deliberately chosen to resemble the legitimate and unrelated crypto-js library. Axios's own code never called it. It did not need to. The dependency's job was to run automatically on install.


The malicious versions went live at 00:21 UTC and were removed by 03:15 UTC, the maintainer's own words, in a public post-mortem he published on GitHub within two days of the incident. Two hours and fifty-four minutes. That is the entire window.

Inside that window, the injected dependency ran a dropper that downloaded platform-specific payloads for macOS, Windows, and Linux, then deleted itself and restored a clean copy of package.json to erase the evidence. The resulting remote access trojan beaconed to its command server every 60 seconds, capable of remote shell execution, file browsing, process listing, and system reconnaissance, according to Wiz's own indicator-of-compromise analysis. Huntress separately confirmed active exploitation, observing at least 135 endpoints across all three operating systems contacting the attacker's infrastructure during the exposure window.


Here is the detail that made me actually stop and think, rather than just filing this under "supply chain attacks happen." Huntress found that even on the branch of axios where modern OIDC-based trusted publishing had been configured, the CI/CD workflow still passed a long-lived NPM_TOKEN as a fallback environment variable alongside the OIDC credentials. When both are present, npm defaults to the token. The more secure authentication method was live. It just was not the one actually being used, because a legacy credential nobody had gotten around to removing was still sitting there, quietly taking priority every time.


That is not a story about axios being careless. It is a story about how a project can genuinely believe it has fixed a specific risk while a forgotten fallback silently keeps the old exposure alive. I recognized the shape of that mistake immediately, because it is the same shape as my own.


That npm install axios could have been a developer doing routine maintenance. It could just as easily have been an agent running a dependency update as part of a larger task, at 2am, with nobody watching. The package had been trusted for years. Your agent had no reason to question it. Neither did you.


For me personally, the blast radius would have been ugly: SSH keys to client infrastructure, Cloudflare, GitHub, GitLab, platform credentials across a dozen services. One key out, and the question stops being whether damage happens. It becomes how fast it spreads before anyone notices.



The Four-Layer Credential Containment Model


Named framework: The Four-Layer Credential Containment Model.


No single control here makes this AI agent security problem disappear. I want to say that first, because every article about security implies that following the steps fixes it, and it does not. What these four layers actually do is shrink the blast radius at each point where a key could leak, so that no single failure, an exposed key, a compromised package, a careless paste into a chat window, is enough on its own to produce a four-figure surprise or worse.


Layer

What It Prevents

Effort to Implement

Residual Risk If Skipped

IP or network restriction

A leaked key being usable from anywhere on earth

About 15 minutes per key, on any serious provider (Cloudflare, AWS, GCP, Google)

The single most underused control available. A key restricted to your production server's IP is not worthless if it leaks. A key that works from any IP is a loaded weapon someone else can pick up.

Spending caps set low

A billing alert arriving after the damage is already done

Minutes to configure, occasional adjustment as usage grows

An alert set at your actual budget ceiling is not a warning, it is a receipt. Set thresholds around 20% of expected spend so you hear about a problem while it is still small.

Key expiry and rotation

Standing access accumulating invisibly long after the task it was granted for is finished

Requires discipline more than tooling

This is the one I am genuinely worst at. Every time I grant a key for a one-off task I tell myself I will revoke it afterward. Three months later it is still live and I have completely forgotten it exists. I know this about myself and I still do it.

Architectural: the agent never holds the key

Every leak vector above simultaneously, chat history, environment files, project context, logs

Requires real engineering work: a broker that injects credentials directly into outgoing calls

The deepest fix and the only one that addresses the agent-specific risk directly. Hardware-backed storage, like Apple's Secure Enclave, takes this further: encrypted at the chip level, unreachable even if the machine is compromised at the software layer. The attack surface does not go to zero. It gets close.

The first three layers are things you can implement this afternoon. The fourth is the one that actually changes the shape of the problem rather than just narrowing it, because it removes the credential from every location an agent, or an attacker who has compromised something your agent trusted, could ever reach it.



What Breaks Without These Layers


  • Assuming a public-by-design key is automatically safe. A frontend-exposed key is fine for what it was originally scoped to do. It stops being fine the moment anyone, including a well-meaning teammate, enables a paid capability on the same project without re-scoping the key itself.


  • Treating a budget alert as a safeguard. By the time the alert fires, the spend has usually already happened. An alert is a notification, not a circuit breaker, unless it is paired with an actual spending cap that halts usage.


  • Trusting a package because it is popular. Axios had over 100 million weekly downloads and had been trusted by nearly every JavaScript project in existence for years. Popularity is not the same signal as safety. It is, if anything, exactly what makes a compromised maintainer account so much more valuable to an attacker.


  • Forgetting that OIDC or any modern auth method is only as secure as what still runs alongside it. The axios incident's root cause was not a failure of trusted publishing. It was a legacy token nobody had removed, still active as a silent fallback. Auditing what your system defaults to when two credentials are present is not optional once you have adopted a more secure method. The old one has to actually be gone, not just deprioritized on paper.


  • Pasting keys into chat windows because the workflow makes it feel natural. It felt natural to me too. That is exactly the problem. The decision never registered as a security decision because the interface never asked me to treat it like one.


That is the actual lesson from both stories, mine and axios's. Neither incident needed a sophisticated attacker exploiting a sophisticated flaw. Mine needed one forgotten API scope. Theirs needed one forgotten token nobody had gotten around to removing. The damage in both cases was decided long before either problem became visible, by whatever had been left reachable in the meantime.



FAQ


Q: How do AI agents leak API keys?

A: An AI agent typically needs a credential to perform tasks involving real infrastructure: hitting an API, configuring a server, pushing code. That credential is commonly provided directly in a chat prompt, stored in an environment file the agent can read, or embedded in project context the agent has ongoing access to. From any of those locations, the credential can be exposed through chat history logs, accidental inclusion in committed code, or exploitation of a compromised dependency the agent trusted, such as a backdoored package installed during a routine update task with nobody watching the process.


Q: What happened in the axios npm supply chain attack?

A: On March 31, 2026, an attacker compromised the npm account of axios's lead maintainer and published two malicious versions, 1.14.1 and 0.30.4, of the widely used HTTP client library, which has over 100 million weekly downloads. The malicious versions added a trojanized dependency called plain-crypto-js that silently installed a cross-platform remote access trojan on any system that ran npm install during the roughly 2 hour and 54 minute window the compromised versions were live, confirmed directly by the maintainer's own public post-mortem. Huntress documented active exploitation across all three major operating systems during the exposure window.


Q: Why did the axios attack succeed even though the project used modern OIDC-based publishing security?

A: Huntress found that even on the branch configured with OIDC trusted publishing, the CI/CD workflow continued passing a long-lived NPM_TOKEN as a fallback environment variable. When both an OIDC credential and a static token are present, npm defaults to using the token. The more secure authentication method was technically configured and functionally bypassed by a legacy credential that had never been removed, illustrating that adopting a more secure method does not close a vulnerability unless the older, less secure method is actually eliminated rather than simply left in place alongside it.


Q: What is the most effective way to protect API keys used by AI agents?

A: The most effective single control is architectural: prevent the agent from ever holding the raw credential at all, using a broker or credential-injection system that supplies the key directly to the outgoing call without it ever appearing in chat history, logs, or environment files accessible to the agent. Short of that, IP or network restriction limiting a key's usability to specific trusted addresses, low spending caps set around 20% of expected usage rather than at the actual budget ceiling, and strict key expiry with no standing access left over from completed tasks each meaningfully reduce the blast radius of any single credential leak.


Q: Can a supply chain attack on a popular package like axios actually affect a business that has nothing to do with the compromised project directly?

A: Yes. Any project, human-run or agent-run, that executed a routine dependency update during the exposure window was affected regardless of that project's own security practices, because the compromise happened at the distribution level of a trusted, widely used package rather than through any action the affected project took. This is precisely why popularity and long-standing trust in a dependency are not substitutes for maintaining credential hygiene independent of how safe any specific package is assumed to be.



Client reviews: Trustpilot · Clutch · G2 · DesignRush · GoodFirms


Published: July 24, 2026

Last Updated: July 24, 2026

Version: 1.1 (TLDR, Answer block added, Schema updated, Irish Tech News coverage added, Introduces the Four-Layer Credential Containment Model framework. Sources: Wiz technical analysis, Huntress incident reporting, Elastic Security Labs, Datadog Security Labs, axios maintainer's public GitHub post-mortem.)

Verification: All claims in this article are verifiable via llms.txt and public sources

Comments


bottom of page