A small software team can ship a product containing code written by thousands of people it has never met.
That is normal.
The team installs a web framework, logging library, database driver, image processor, authentication package and a pile of smaller dependencies underneath those dependencies. Nobody writes all of this from scratch because doing so would be slow, expensive and probably less secure.
Modern software is assembled.
The awkward part is that every borrowed piece becomes part of the product’s supply chain.
The dependency you installed has dependencies too
Developers usually see the package they chose.
They run one command, add one library and get a useful feature.
Behind that library may be ten more packages. Those packages may depend on others. A project can accumulate hundreds or thousands of components without anyone deliberately selecting each one.
This is not automatically bad. Reuse is one of software’s superpowers.
But it changes the security question.
You are not only asking, “Is our code safe?” You are also asking, “What code did we bring in, where did it come from, who can update it, and what happens if one part becomes malicious or vulnerable?”
That is software supply chain security in ordinary language.
Trust enters through the build system
People often imagine attacks happening after software is deployed.
A criminal breaks into the server. A malicious request exploits a bug. A password is stolen.
Supply chain attacks can begin earlier.
A popular package is compromised. A maintainer account is hijacked. A build pipeline pulls a malicious dependency. A fake package with a familiar name is published and someone installs it by mistake.
The poisoned code can then travel through a trusted development process and arrive inside a legitimate release.
That is what makes supply chain attacks uncomfortable. The bad thing may enter through a path designed for good things.
The build system trusts the dependency because the developer told it to.
“Latest” is not a security strategy
Keeping dependencies updated is generally sensible. Old versions accumulate known vulnerabilities and compatibility problems.
But blindly updating everything the moment a new version appears is not wise either.
New releases can contain bugs. Accounts can be compromised. Behaviour can change. A major version may break assumptions your application depends on.
Healthy teams automate dependency updates but still review and test them. They pin versions where appropriate, run tests, monitor security advisories and avoid bringing in a new package for every tiny problem.
Sometimes ten lines of code are better than a dependency maintained by one stranger whose package you now need forever.
Developers like reuse. They should also appreciate subtraction.
An SBOM is an ingredient list for software
One idea gaining attention is the software bill of materials, or SBOM.
The name is refreshingly literal. It is an inventory of components inside a piece of software.
If a serious vulnerability is discovered in a common library, an organisation with a useful inventory can answer an important question quickly: where are we using this?
Without an inventory, the response often begins with a company-wide message asking teams to search repositories and reply in a spreadsheet.
That works eventually. It is not the moment you want to discover that nobody knows what the product contains.
An SBOM does not secure the software by existing. A list is not a shield.
But visibility changes response time.
You cannot patch what you cannot find.
Open source is not the villain here
Supply chain conversations sometimes become lazy criticism of open source.
That misses the point.
Open-source software powers enormous parts of modern technology because sharing common components is efficient. Proprietary dependencies can have vulnerabilities too. Internal packages can be compromised. Commercial vendors can ship bad updates.
The security problem is dependency and trust, not one licensing model.
What does deserve criticism is the way companies sometimes consume open-source projects without understanding their maintenance situation.
A tiny library maintained by one volunteer can end up inside products used by millions of people. The company benefiting from it may contribute nothing back, then become surprised when the project moves slowly.
Supply chains include people, not just files.
Build credentials are more powerful than they look
If an attacker can change source code but cannot release it, the damage may be limited.
If they can compromise the build or release pipeline, the situation becomes much more serious.
This is why CI/CD credentials, package registry tokens, signing keys and release permissions deserve strong protection. Limit who can publish. Use multi-factor authentication. Keep secrets out of repositories. Review unusual changes to build configuration.
The account that publishes your package may be more valuable than the account that edits the README.
Yet teams sometimes protect production servers carefully while leaving release automation with broad, long-lived credentials nobody has reviewed in years.
Attackers notice asymmetry.
Smaller dependency trees are easier to understand
There is a cultural habit in software development: if a package exists, install it.
I think that deserves resistance.
Libraries save time, and many are excellent. But every dependency creates maintenance work. Updates. Compatibility. Licensing. Security monitoring. Documentation. The possibility that the project disappears or changes direction.
Before adding one, ask whether the problem is important enough to justify permanent external code.
For a complex cryptographic operation, please use a well-reviewed library. For turning one string into another in three lines, perhaps do not import half the internet.
Judgment matters.
The supply chain is part of your product
Customers do not care whether a vulnerability lives in your code or a dependency. The product failed either way.
That is the uncomfortable but useful mindset.
Your application includes the packages, build tools, base images, deployment scripts and services required to create and run it. Security has to follow the same boundary.
Know what you depend on. Keep inventories. Update carefully. Protect the accounts and tokens that can publish releases. Remove abandoned packages when the cost of keeping them exceeds the convenience.
Modern software will continue to be assembled from other software.
That is not a weakness.
Pretending the borrowed parts are somebody else’s problem is.





