For years, security focused on the code teams wrote and the servers they ran. The SolarWinds and XZ Utils incidents made it impossible to ignore a different attack surface: the supply chain that produces your software. Modern applications are assembled from thousands of third-party packages and built by automated pipelines, and attackers have learned that compromising what you build with is often easier than attacking what you built.
Your dependencies are your attack surface
Most of the code in a typical application was written by someone else. Every package you install, and every package those packages depend on, is code you are trusting and running. A single malicious or compromised dependency deep in that tree can execute in your build or your production environment. Treating dependencies as trusted by default is the core mistake, and it is the same lesson as the vulnerable-components category in our OWASP Top 10 guide.
Know exactly what you ship
You cannot secure what you cannot see. Maintain an accurate inventory of your dependencies, often formalised as a software bill of materials, so that when a vulnerability is announced you can answer within minutes whether you are affected. Teams without this visibility spend days during a major disclosure simply trying to find out if they are exposed.
Pin and verify what you install
Use lock files so builds are reproducible and an attacker cannot silently slip a different version into your tree. Verify integrity hashes so a tampered package is rejected. Be deliberate about adopting brand-new versions immediately, since a compromised release is most dangerous in the window before the community notices. Reproducibility here is the same discipline that keeps a CI/CD pipeline trustworthy.
Watch for dependency confusion
Dependency confusion attacks trick your build into pulling a malicious public package in place of an intended internal one by exploiting how package managers resolve names. Configure your tooling so internal packages always resolve from your private registry and cannot be shadowed by a public package of the same name. This is a specific, well-documented attack that a few configuration choices prevent.
The build pipeline is production
Your CI/CD system has access to source code, secrets, and the ability to deploy, which makes it one of the most valuable targets you own. Apply least privilege to pipeline credentials, scope tokens narrowly, avoid running untrusted code with access to your secrets, and audit who can change pipeline configuration. A compromised pipeline can inject malicious code into a perfectly clean codebase, which is exactly how the most damaging supply chain attacks have worked. Securing it is a direct application of zero trust to your own infrastructure.
Scan continuously, not once
New vulnerabilities are disclosed in existing dependencies every day, so a one-time scan is nearly worthless. Build automated dependency and image scanning into the pipeline and run it continuously, so a newly disclosed issue in a package you already use is flagged promptly rather than discovered by an attacker. This pairs naturally with the input and authentication controls in our API security checklist.
Sign and verify your artifacts
Sign the artifacts your pipeline produces and verify those signatures before deployment, so only artifacts that came from your trusted build process can reach production. This closes the loop: even if an attacker can place a file where deployment looks for it, an unsigned or wrongly signed artifact is rejected.
Make it a standing practice
Supply chain security is not a project you finish but a posture you maintain, because the dependency tree and the threat landscape both change constantly. Inventory, pin, scan, least-privilege your pipeline, and sign your builds, and revisit all of it regularly. If you want your build pipeline and dependencies secured and monitored by specialists, our security and QA team does exactly that, and you can talk to us about a review.