One of the highest priorities for our Security program at Endor Labs has been to ensure our platform is strengthening the security of our own application, especially as more of our code is written by agents. This means the Security team at Endor Labs is “customer zero” of new features so that we can help validate our value proposition and polish sharp edges before they hit our customer base.
So let’s talk about one of our newer products: the Endor Labs Package Firewall. It was released in May to help organizations stop software supply chain attacks by preventing installs of malicious packages on developer laptops, or in CI/CD pipelines. The firewall (1) enforces a cooldown policy so that package versions need to be a sufficient age to be installed and (2) cross-checks package versions against our malware database in the case that the malicious version is available on the registry beyond the cooldown period.
My team rolled out the package firewall internally ahead of its release. In doing so, we’ve learned quite a bit about the part of the software supply chain that never makes it into code, and we’ve worked with our Product and Engineering teams to improve the developer experience for firewall interactions.
And importantly, the firewall has already proven value: we discovered a few software supply chain near misses in our firewall logs after rolling the feature out.
Philosophy
I’ll admit, at first I was a firewall skeptic. The basic idea of a package firewall is that if you can get all software installed through it, you are entirely protected from software supply chain attacks. Sounds easy, right? But how feasible is that?
The prospect of achieving 100% coverage and minimal interruption seemed daunting. Either you need to route traffic to package managers through a proxy or deploy package manager configurations on all of your servers. And, with both methods, you need to monitor for tampering with the setup.
And what about the developer experience? Will this be too heavy-handed? Will developers notice added latency?
So, I went into this roll-out with lots of questions and a heavy dose of skepticism; questions that we see echoed from customers all the time. There was nothing to do however, but to roll up my sleeves, deploy, and figure it out!
The rollout
For initial deployment, we decided to route package managers on developer machines directly through our firewall. Our team worked with engineering to iterate on MDM scripts to set the necessary configurations for each ecosystem on all of our corporate endpoints. We configured a 24-hour cool-down policy, ensuring package versions published within the last 24 hours would not be served through our firewall, in addition to blocking package versions identified by Endor Labs as malicious.
We are currently monitoring endpoints for configuration drift, but this is an area I’d like to mature. We are exploring comparing package firewall logs with EDR process events. Ideally, when an install process is detected, we should see a corresponding log in the Endor Labs platform, if not, an alert should fire.
The early insights
While my initial skepticism was focused on potential gaps in coverage, the rollout immediately made it clear how often we had brand new package versions being installed on developer machines. This was the first time we had granular visibility into the age of packages being pulled in across the organization. We ended up averaging about 135 events a day where a new (within the last 24 hrs) and potentially unverified package version would have been pulled in sans firewall: ~1 event per developer. The firewall has also highlighted that in the age of agentic coding, the “developer” population encompasses more than just software engineers: 21% of our package firewall events fall outside of engineering.
By comparing package firewall logs to our coding agent telemetry logs, we found a majority of installs are coming from within agent sessions. Further, we detected several instances of an agent hitting a firewall block, and then attempting to work around the firewall configuration (we detected and blocked this behavior with our Coding Agent Governance product, which I’ll leave for a future blog post).
The firewall also shed some light on the number of installs that occur without explicit action from humans or agents. To name a few things that we observed in the “auto-update” category:
- Anthropic is shipping new versions of Claude Code constantly and, by default, auto-updates Claude Code depending on how the application was installed.
- Many local MCP server configurations use
npxanduvxto pull in packages by default. This will default to pulling and caching the latest version (see our own MCP server) or, if the@latesttag is specified, pulling the latest version every time the coding agent is launched. - VS Code extensions don't stop at the VSCode / OpenVSX marketplace. As an example, the Go extension is installed from the marketplace but then fetches its Go-side tooling –
vscgo, gopls, dlv– directly from the Go module proxy. VSCode extensions are set to auto-update by default.
In general, there was more package install activity than I had previously anticipated and the rollout gave us detailed insight into human, agent, and application behavior when it comes to installing packages.
The early feedback
Initially, there was a high number of blocked installs, so a ton of engineering investment was quickly directed towards examining and improving the developer experience.
Over 99% of the time, when the latest package version is installed, the package manager is simply resolving to that version; the developer or agent isn’t explicitly asking for it. We quickly realized that the biggest DevEx improvement — by far — would be to refrain from blocking those installs and instead serve the latest compliant version. We call this “curation” as we are removing non-compliant versions from the list we are sending back to the package manager, and the package manager pulls a version from the curated list. After “curation” was released, the number of suppressed versions stayed the same (~135 / day), but blocked installs (and accompanying frustration) in supported ecosystems (Python, JS) became almost non-existent.
Also, when the firewall blocks an install, the package manager offers limited feedback: developers see a log with the 403 error(s) and package location(s), but limited explanation of why the install was blocked (is the package malicious, or just too new?). This was a source of developer frustration. In response, the team added a Slack app to the product. Now, users are immediately messaged with the detailed reason for the blocked install.
After these improvements, the package firewall was hardly visible to our developers. On the rare occasion that it did block an install, the developer immediately knew why.
The ultimate security impact
Finally, after several months of using our package firewall, the security impact has been easy to prove. Our firewall data shows several instances of near misses where a benign package version was successfully installed within hours of that package having a compromise (most recently, with the npm package keyv).
Each of those events thus far occurred after the package was taken down, but this has reinforced the notion that an attempted download of a malicious package from a developer / agent / application auto-update is inevitable.
But, thanks to the package firewall, that inevitable attempt doesn’t need to lead to a supply chain compromise. And, importantly, this level of protection is possible with minimal friction for developers.
What's next?
When you're ready to take the next step in securing your software supply chain, here are 3 ways Endor Labs can help:









