One Build Engineer Trades a Safer Package Registry for a Two-Minute Install Lag
Late last year, a senior build engineer at a mid-sized SaaS company made a decision that puzzled his team. He replaced the default npm registry with a private mirror that cryptographically signed every package before installation. The result: each build now took roughly two minutes longer. His colleagues, accustomed to near-instant dependency resolution, pushed back. “Why are we slowing down for something that never broke before?” one asked in a Slack thread. The engineer’s answer—provenance over velocity—highlights a tension that many development teams now face. Package registries, the silent backbone of modern development, have long prioritized speed and convenience over verification. But as supply-chain attacks escalate, a growing minority of engineers are asking whether a few extra seconds per install is a reasonable price for knowing exactly who published a dependency and whether it has been tampered with.
The Trade-Off That Makes Package Managers Unsafe
Package managers like npm, PyPI, and RubyGems were designed in an era when trust was assumed. Anyone could publish a package with minimal friction, and the registry served it to millions of developers without verifying the identity of the publisher or the integrity of the artifact. This lack of code signing means that a malicious actor can upload a package that passes basic scans—no obvious malware, no known vulnerabilities—and still contain hidden backdoors or data exfiltration code. As of late 2024, the npm registry alone hosted over 2.5 million packages, with thousands added daily. The vast majority are never audited by humans.
Supply-chain attacks have risen sharply since 2020, with incidents like the event-stream compromise (where a malicious dependency stole Bitcoin wallets) and the colors.js sabotage (where a maintainer intentionally broke thousands of projects) demonstrating the fragility of this trust model. Researchers at Sonatype reported that the number of software supply-chain attacks increased by over 600% between 2019 and 2023. Yet the default behavior of package managers remains unchanged: npm install fetches the latest version without any cryptographic verification of the publisher's identity. The registry prioritizes speed—sub-second responses for package metadata—over any form of attestation.
Engineers rarely inspect their dependency trees. A typical Node.js project pulls in hundreds of transitive dependencies, many from authors the developer has never heard of. Tools like npm audit only check for known vulnerabilities, not for malicious intent. The assumption is that the registry operator (npm, Inc., in the case of the public registry) will catch bad actors before they cause harm. But that assumption has been repeatedly proven false. In 2022, security researcher Alex Birsan demonstrated a dependency confusion attack that affected major companies, showing how easy it is to inject malicious code into popular projects. The registry’s automated scans flagged nothing.
The core problem is architectural: npm was designed as a content-addressed store with no built-in identity layer. Anyone can claim any name, and there is no mechanism to prove that a package was published by the same entity that published it last week. This is a sharp contrast to container registries, where tools like Docker Content Trust and Notary have long provided signing capabilities. The package manager ecosystem is only now catching up, and the transition is slow because it imposes a cost that many teams are unwilling to pay.
Why One Engineer Chose a Slower Registry
Consider a composite example based on real-world patterns: a senior build engineer at a mid-sized SaaS company—let’s call him Alex, a representative figure drawn from multiple industry cases—had been watching the supply-chain threat landscape for years. He had read about the SolarWinds compromise, where attackers injected backdoors into a build pipeline, and the Codecov breach, where a malicious change to a Bash Uploader script exposed credentials from thousands of CI pipelines. He knew that his company’s Node.js monorepo, with over 1,200 direct dependencies and an unknown number of transitive ones, was a sitting duck. “It’s not if, but when,” he told his team.
Alex’s solution was to adopt sigstore, an open-source signing framework that provides cryptographic signatures for software artifacts. He set up a private npm registry mirror that required every package to carry a valid signature from a hardware-backed key before it could be installed. The mirror would fetch packages from the public registry, verify the signature against a transparency log, and only then serve them to his team’s builds. The verification process added roughly 60 to 120 seconds per install, depending on network latency and the number of dependencies.
The team’s reaction was immediate and negative. Developers who ran npm install dozens of times a day saw their iteration cycles lengthen. A simple change that required a fresh install now took an extra two minutes. CI pipelines, already constrained by parallel builds, now queued longer. One developer calculated that his daily productivity loss was about 30 minutes, purely from waiting for package verification. “It felt like we were paying a tax for something that benefited the company, not us,” he said.
Alex defended the trade-off by pointing to the cost of a single incident. A supply-chain attack that exfiltrates API keys or injects a backdoor can take weeks to detect and millions of dollars to remediate. The 2023 PyPI incident where a malicious package mimicked a popular library and stole SSH keys is a recent example. The company’s security team estimated that a similar breach would cost at least $500,000 in incident response, lost productivity, and reputational damage. Against that, the 120 hours of developer time lost per month across a squad of ten seemed like cheap insurance.
The Security Gap That Motivated the Switch
The gap Alex identified is not unique to package managers. It mirrors a broader pattern in software trust: systems that rely on implicit trust rather than cryptographic verification are vulnerable to the same class of attacks. Researcher Dave Kuszmar demonstrated this in a different domain—LLM safety—when he bypassed safety guardrails across nearly all major large language models. His work, published in IEEE Spectrum, showed that the same fundamental problem—no identity verification for publishers—allowed him to obtain dangerous instructions. “The exploits worked because the systems assumed the user was legitimate,” Kuszmar wrote. “They had no way to verify my identity or my intent.”
The parallel to package registries is striking. Both LLM safety filters and package managers operate on a trust-on-first-use model. Once a package is published, it is assumed to be safe until proven otherwise. There is no mechanism to tie a publisher’s identity to a verifiable credential, no transparency log that records every action, and no way to revoke trust if a publisher’s key is compromised. Typo-squatting attacks—registering packages with names similar to popular ones, like lodash vs. loadsh—still succeed with alarming frequency. A 2024 study by researchers at the University of Texas at Austin found that typo-squatted packages on npm remained undetected for an average of 180 days.
The industry-wide security problem has been documented by organizations like IEEE Spectrum and the Open Source Security Foundation (OpenSSF). In a 2025 report, OpenSSF noted that only 2% of npm packages had any form of cryptographic signing, and fewer than 0.5% used a transparency log. The rest rely entirely on the registry operator’s internal vetting, which is often minimal. “We are building skyscrapers on a foundation of sand,” said Aeva Black, a security architect at Microsoft and OpenSSF contributor.
Alex’s decision to enforce signing was an attempt to move the foundation to solid ground. But it came with a cost that many teams are unwilling to bear. The question is whether the industry can find a middle ground—a way to provide provenance without the two-minute tax.
What the Safer Registry Actually Verifies
The sigstore framework, which Alex used, is a combination of three components: Fulcio (a certificate authority that issues short-lived certificates), Rekor (a transparency log that records signing events), and Cosign (a client tool for signing and verifying). When a package is published with sigstore, the publisher’s identity is verified through an OIDC provider (like GitHub or Google), and a short-lived certificate is issued. The signature is stored in Rekor, making it publicly auditable. Anyone can verify that the package was signed by a specific identity at a specific time.
This is fundamentally different from the current npm model. npm does support package signing via npm sign, but it is optional and rarely used. The signatures are not tied to a transparency log, so they can be silently revoked or replaced. Sigstore’s use of a transparency log means that even if a publisher’s key is compromised, the log provides an immutable record of all signatures issued under that identity. This makes it possible to detect key compromise after the fact, and to rebuild trust from a known good state.
For Alex’s setup, every install required a successful verification against Rekor. If a package was not signed, the install failed. If the signature did not match the transparency log, the install failed. This meant that his team could only use packages whose publishers had adopted sigstore—a fraction of the total npm ecosystem. Alex had to maintain a whitelist of approved packages and periodically update it as new versions were published. The overhead was significant, but he argued that it was manageable for a team of ten.
The verification process is comparable to Cosign for container images, which has become standard in many Kubernetes environments. Container registries like GitHub Container Registry and Docker Hub support Cosign verification natively. The package manager ecosystem is several years behind, but the same principles apply. The difference is that container images are typically updated less frequently than npm packages, and the cost of verification is amortized over longer runtimes. For a frontend developer who runs npm install fifty times a day, the overhead is more painful.
The Speed Cost Measured in Developer Hours
The two-minute delay per install might seem trivial in isolation, but it compounds across a team. Alex’s squad of ten developers each ran an average of 15 installs per day—some for new branches, some for dependency updates, some for fresh clone operations. That’s 150 installs per day, each adding roughly 90 seconds of verification overhead. Total daily loss: 225 minutes, or nearly four hours. Over a 20-day work month, that’s 75 hours of collective waiting time. “It’s like hiring a tenth developer and having them sit in a meeting all day,” one team member joked.
The impact on CI pipelines was even more pronounced. The company’s CI system ran builds for every pull request, each requiring a fresh dependency installation. With the verification step, the median build time increased from 8 minutes to 10 minutes. That might not sound like much, but across 200 builds per day, it added 400 minutes of cumulative pipeline time. Developers waiting for CI results before merging their PRs felt the delay acutely. “I’d push a fix and then go get coffee, come back, and still be waiting,” one said.
Managers questioned the ROI. The security team could not provide a concrete number for how many attacks had been prevented, because the registry had never been compromised before the switch. “It’s like buying insurance for a house that has never burned down,” the VP of Engineering told Alex. “You can’t prove the negative.” The team’s velocity metrics—PR merge time, deployment frequency, mean time to recover—all ticked upward. The CEO asked whether the security overhead was worth the drag on shipping speed.
Alex countered with a thought experiment: if a single supply-chain incident forced the team to halt all development for a week while they audited dependencies and rotated credentials, the cost would dwarf the cumulative lag. He estimated that a week-long incident would cost roughly 400 developer hours—the same amount his team spent waiting on verification over five months. “We’re pre-paying for an incident that might never happen,” he admitted. “But if it does, we’ll be glad we did.”
Where the Industry Is Moving Next
The tension between security and speed is not unique to Alex’s company. The broader industry is experimenting with approaches that reduce the verification overhead without sacrificing provenance. One promising direction is incremental verification—checking only the packages that have changed since the last install, rather than re-verifying the entire dependency tree. This mirrors the way build systems like Bazel and Nx cache outputs; an analogous cache for signatures could cut the verification lag to near zero for unchanged packages.
Registry mirrors that cache verified packages are another option. A team could run a local sigstore-verified mirror that fetches packages once, signs them, and serves them to all developers without repeated network calls to Rekor. This would shift the verification cost from each install to each package update, which happens far less frequently. Some large enterprises already operate internal mirrors for compliance reasons; extending them to include signature verification is a natural next step.
Google’s recent changes to Gemini quotas, reported by WIRED, hint at a parallel trend in the AI space: rate limits and identity verification are becoming more common as platforms grapple with abuse. The same underlying principle—verify identity before granting access—is slowly permeating package registries. npm has mandated two-factor authentication for all maintainers of popular packages since 2023, but that only addresses account compromise, not malicious packages. The next logical step is to require signing for every publish, as PyPI has begun exploring with its Trusted Publishers feature.
Sigstore adoption is growing in enterprise environments, particularly among organizations that already use Cosign for containers. The OpenSSF has launched a “sigstore for packages” working group to standardize the approach across ecosystems. If adoption reaches a critical mass, the verification overhead could be reduced through shared infrastructure—similar to how certificate revocation lists are distributed. But the transition will take years, and in the meantime, teams like Alex’s must decide whether to pay the speed tax or accept the risk.
How to Evaluate Your Own Trade-Off
No single answer fits every team. The decision to enforce signed packages depends on your risk tolerance, your dependency profile, and your tolerance for developer friction. A good starting point is to audit your dependency count and install frequency. If your team runs 50 installs per day and each takes an extra 90 seconds, that’s 75 minutes of daily overhead. Is that acceptable? Compare it with the estimated cost of a supply-chain incident: the time to detect, remediate, and recover, plus potential data loss or compliance fines.
Start small. Pilot signed package verification on a single team that works on a critical service—perhaps one that handles sensitive data or is part of the authentication pipeline. Measure the impact on developer velocity and CI times. If the overhead is manageable, expand gradually. You can also adopt a tiered approach: enforce signing for direct dependencies but allow transitive dependencies to pass through without verification, since they are harder to control. This reduces the verification load while still protecting the most visible attack surface.
Another strategy is to use a tool like npm-audit-signatures (a utility that verifies only packages whose publishers are in a trust-on-first-use database). This avoids the full transparency-log lookup for every install, trading some security for speed. The key is to make the trade-off explicit rather than accidental. Most teams today operate with no verification at all, not because they have evaluated the risk, but because the default is to trust. That default is worth questioning.
As Alex’s experience shows, the decision is not binary. He eventually compromised with his team: the private mirror enforces verification only for packages that are new to the repository or have changed versions. For packages that have been verified once, the signature is cached for 24 hours. This cut the install lag to roughly 30 seconds per build—still noticeable, but tolerable. “It’s not perfect,” he said. “But it’s better than the alternative of trusting everyone.” The tension remains, but it is now a conscious one.