Authentication Methods That Work in 2026
Passwords are still everywhere but passkeys, WebAuthn, and modern OAuth flows have matured enough to replace them for...
8 min read
09.03.2026, By Stephan Schwab
Every modern software project relies on hundreds or thousands of external dependencies. When one of those dependencies is compromised, the malicious code runs with full trust inside your systems — and your customers' systems. Supply chain attacks have brought down companies and eroded trust in entire ecosystems. Understanding this risk is no longer optional for anyone responsible for software delivery.
In early 2021, a security researcher demonstrated something terrifying. By uploading packages to public registries with names matching internal packages used by major corporations, he achieved code execution inside Apple, Microsoft, Tesla, and dozens of other companies. The attack worked because package managers automatically prioritized public packages over internal ones.
He didn’t exploit a bug. He exploited trust.
This wasn’t an isolated incident. The same pattern repeats across the software industry:
Each incident follows a similar arc: a trusted component is compromised, and the malicious payload spreads automatically to everyone who depends on it.
Traditional security thinking focuses on perimeters. Firewalls protect networks. Authentication protects systems. Code review protects repositories. But supply chain attacks bypass all of these because they arrive through the front door, wearing the uniform of trusted code.
When your build system fetches dependencies, it implicitly trusts that those packages contain exactly what their maintainers intend. That trust is recursive — the package you depend on has its own dependencies, which have their own dependencies, forming a tree that can include thousands of components.
A single compromised node in that tree compromises everything above it.
Modern applications amplify this risk. A typical JavaScript application might depend on 300-1,500 packages when you count the full transitive tree. A Python project might have 50-300. Each dependency is a potential entry point. Each maintainer is a potential target.
For executives, this is fundamentally a risk management problem. And it’s one that traditional governance structures are poorly equipped to handle.
The exposure is enormous. If your company ships software — whether as a product, a SaaS application, or internal tools — you’re distributing code you didn’t write and can’t fully audit. That code runs with the same privileges as your own. A compromise in a logging library affects every service that uses it.
Detection is difficult. Malicious code in dependencies is designed to evade detection. It may activate only under specific conditions, lie dormant for months, or disguise itself as legitimate functionality. Standard code review processes rarely examine dependency updates with the same rigor as internal changes.
Response is expensive. When a supply chain compromise is discovered, the remediation effort can be massive. Every affected system must be identified, patched, and verified. Customer communications must be handled. Regulatory obligations may be triggered. The SolarWinds cleanup cost affected organizations hundreds of millions of dollars.
Reputation damage is severe. Customers don’t distinguish between “your code had a vulnerability” and “a library you used had a vulnerability.” The breach happened through your software. The responsibility is yours.
The Node.js package ecosystem illustrates both the power and peril of modern dependency management.
NPM hosts over two million packages. Millions of developers depend on it daily. The ecosystem’s openness has fueled extraordinary innovation — anyone can publish a package, and anyone can use one.
That same openness creates attack surface.
Packages are often maintained by individuals with no security resources. Transfer of ownership is trivially easy. Typosquatting (publishing malicious packages with names similar to popular ones) is a constant threat. And the interconnected nature of JavaScript development means a single compromised package can reach millions of applications within hours.
Consider what happens when you run npm install:
At any step, a compromise can occur. And the developer running the command may never know.
For years, the calculus was simple: why spend two days implementing date parsing, CSV handling, or string manipulation when a well-tested library exists? The time saved justified the dependency added.
Generative AI changes this equation dramatically.
Tasks that once took hours or days — implementing a left-pad function, parsing a specific file format, handling common data transformations — now take minutes. You describe what you need, review the generated code, write tests, and you’re done. No dependency added. No supply chain risk introduced. No maintainer to trust.
This doesn’t eliminate the need for dependencies. Complex libraries encoding deep domain expertise — cryptography, database drivers, machine learning frameworks — still make sense. You want battle-tested implementations for security-critical code.
But for the hundreds of small utilities that accumulate in a typical project? The ones that exist because someone didn’t want to write thirty lines of straightforward code? Those are now candidates for in-house implementation. Every dependency you don’t add is attack surface you don’t create.
The irony is rich: AI, often discussed as a security risk, may prove to be one of the most effective defenses against supply chain attacks — by making it practical to simply write more of your own code.
The goal isn’t to eliminate dependencies — that would mean abandoning the productivity gains that modern ecosystems provide. The goal is to manage the risk intelligently.
Lock your dependencies. Use lock files (package-lock.json, Pipfile.lock, Gemfile.lock) and commit them to version control. This ensures reproducible builds and prevents silent updates.
Pin specific versions. Avoid version ranges that automatically pull in new releases. Treat dependency updates as explicit changes requiring review.
Audit regularly. Tools like npm audit, pip-audit, and Snyk can identify known vulnerabilities in your dependency tree. Integrate them into your CI/CD pipeline so every build is checked.
Scan your containers. Container images bundle your application with its entire dependency tree. Tools like Trivy, Grype, Clair, and commercial offerings from Docker, AWS, and Google can scan images for known CVEs before deployment — and continuously monitor running containers. A vulnerability in a base image or installed package triggers an alert, not a breach.
Generate and maintain SBOMs. A Software Bill of Materials documents exactly what’s in your deployable artifacts. Tools like Syft, CycloneDX, and SPDX generators create machine-readable inventories. When a new CVE is announced, you can immediately identify which systems are affected rather than scrambling to audit.
Minimize your attack surface. Every dependency is risk. Before adding a package, ask: Can we implement this ourselves? Is this maintained? What does its dependency tree look like?
Verify integrity. Use package integrity checking (npm’s package-lock.json includes integrity hashes). Consider using a private registry that mirrors only approved packages.
Monitor for compromises. Subscribe to security advisories for critical dependencies. Use tools that alert on unexpected changes in package behavior or ownership. Services like Socket.dev analyze packages for suspicious behaviors — install scripts that phone home, obfuscated code, unexpected network access.
Review dependency updates. Treat updates to dependencies with the same rigor as internal code changes. Automated tools like Dependabot, Renovate, and Snyk can flag suspicious modifications and provide context for review.
Technical defenses are necessary but insufficient. Supply chain security requires organizational commitment.
Make it a board-level concern. The potential impact of supply chain attacks — financial, regulatory, reputational — merits executive attention. Ensure leadership understands the exposure and funds appropriate defenses.
Invest in tooling. Software composition analysis (SCA) tools, dependency scanning, and private registries cost money. That investment is insurance against catastrophic loss.
Train developers. The people closest to the code need to understand the risks and the practices that mitigate them. Security awareness isn’t just about phishing emails.
Establish policies. Define what sources are acceptable for dependencies. Set standards for vetting new packages. Create processes for responding to discovered vulnerabilities.
Maintain an inventory. You can’t secure what you don’t know about. Software Bills of Materials (SBOMs) provide visibility into what your applications actually contain.
No defense is complete. The nature of supply chain attacks means that a sufficiently sophisticated adversary can eventually find a way in. A determined attacker targeting the maintainer of a package you depend on may succeed. A state-sponsored operation may compromise infrastructure you have no visibility into.
The goal is not perfection. The goal is resilience.
Build systems that detect compromise quickly. Design architectures that limit blast radius. Practice incident response before you need it. And accept that dependency on external code — which is unavoidable in modern development — carries inherent risk.
Supply chain attacks exploit the trust that makes modern software development possible. Every library downloaded, every package installed, every framework adopted represents an act of faith — faith that maintainers are competent and honest, that distribution channels are secure, that the code does what it claims.
That faith has been violated enough times to demand action.
For technical teams, this means adopting practices that reduce exposure without abandoning the productivity benefits of shared code. For business leaders, it means recognizing supply chain security as a strategic concern requiring investment and attention.
The next major supply chain attack is not a matter of “if” but “when.” The question is whether your organization will be among those who prepared — or among those who wished they had.
Let's talk about your real situation. Want to accelerate delivery, remove technical blockers, or validate whether an idea deserves more investment? I listen to your context and give 1-2 practical recommendations. No pitch, no obligation. Confidential and direct.
Need help? Practical advice, no pitch.
Let's Work Together