Navigating Software Dependencies and Open Source Inventory Management
Keeping track of software dependencies is not an easy task and only becomes more difficult as companies scale. In this blog, we explore the types of dependencies and complications they can cause, as well as available tools and best practices organizations can adopt to improve their open source inventory management.
Understanding Software Dependencies
Software dependency management is a hot topic and an ongoing area for learning and process improvements. They are the byproduct of code collaboration and sharing, and all of us who consume and/or contribute to OSS are potential victims of the consequences if dependencies aren't properly managed. And while not unique to open source software, the rapid proliferation of open source technologies has made tracking software dependencies more complex.
There are two main categories of software dependencies:
- Direct dependencies: This refers to frameworks, libraries, modules, and other software components that an application deliberately and “directly” references to address a solved problem.
- Transitive dependencies: This refers to the cascading list of those independent pieces of software that the direct dependencies in turn include to function properly.
Beyond that, there are some distinctions within those two main categories that are good to be aware of before defining a dependency management strategy:
- Internal vs. External: Some dependencies may be owned and controlled internally by a development team, though typically the vast majority are created and maintained externally.
- Open vs. Closed: Referenced dependencies may be open source allowing development team investigation and ownership by proxy, or they might be binary-only licensed from a vendor where changes are managed through contractual terms.
- Idle vs. Engaged: As the application source evolves, needs change, rendering some dependencies irrelevant. However, they are not always removed from the dependency chain. As a result, some dependencies are actively engaged and used, whereas others are no longer used and remain bundled but idle.
Back to topA software inspection methodology that includes inventorying dependencies and managing lifecycles is essential to system security and sustainability. An up-to-date software inventory is necessary for identifying vulnerable or end-of-life components, and identification is the first step in remediating issues and mitigating risks.
The Challenges of Dependency Management
Today there is an ever-increasing demand for both speed and innovation with regards to software development, and that is both the catalyst for, and the result of, open source software. This demand has also produced software delivery concepts like microservices and container orchestration that require vast amounts of integration points – all of which contribute to the chain of software dependencies. This has ushered in a host of software maintenance problems that require dependency management solutions.
The main challenges that arise are due to the pace of change. It is increasingly more difficult for organizations to keep up with evolving software, as well as the companies, communities, and licensing bodies that maintain and govern them. Some examples:
- Version conflicts: When multiple dependencies within the same application require different versions of a shared library.
- Compatibility issues: When updating a package can introduce breaking changes that require modifications to your application to maintain existing functionality.
- Security vulnerabilities: When a downstream dependency has a known security defect that either needs to be addressed by your application or requires an update to the dependency to remediate it.
- End-of-Life problems: When the referenced software package is no longer maintained by the vendor or community, which can result in security defects that are not remediated and leave your application vulnerable to attacks.
- License compliance: When the application uses another software component in a way that is not allowed by the software license. This can sometimes happen as the result of a license change as versions of the dependency are upgraded.
- Idle bloat: When an application has a growing number of unreferenced dependencies that increase the size, complexity, and liability without adding value.
Few developers are privy to all dependency management best practices, and most teams are not equipped with the tooling necessary to mount a proactive approach to avoid dependency problems. Gone are the days when a development team would settle on a single programming language that allowed them to use a particular package manager (e.g. python:pip, java:maven, javascript:npm, rpm:yum) to list the dependency tree, checklists to track the inventory, and unit tests to validate upgrades. Professionalizing a software development practice now requires modern systems for tackling software dependency management at scale.
Back to topUnbiased Guidance. SLA-Backed Support.
For more than two decades, OpenLogic has partnered with enterprises to help them get the most from their OSS. From migrations to technical support, we can tackle the toughest open source challenges — freeing up your team to focus on innovating for your business.
How to Track Software Dependencies and Manage Your Open Source Inventory
Unfortunately as of this writing, there is no silver bullet in this space. In fact, there is not even a best-in- class solution that has emerged. The good news is, there are software organizations and communities that recognize the problem, and are developing strong solutions to address pieces of this puzzle. Gluing them together can produce an effective system, which is the best path forward for now.
Software Dependency Management Tools
There are a few cornerstone tools that lay the foundation for a modern software dependency management system:
- A central code repository that supports revision control and release versioning (e.g. Git, Github, Gitlab, Helix Core). This is the foundation for dependency discovery, and it can also save and manage lock files that tie an application to a specific version of a dependency.
- A package manager for each programming language or platform (e.g. python:pip, java:maven, javascript:npm, rpm:yum). These tools will handle the interactions (push, pull, install, update, list, etc.) with a dependency repository.
- A Software Bill of Materials (SBOM) generator (Syft, SBOM Tool, Tern, CycloneDX). This will produce an attributed inventory of all the software components in your applications (including supplier name, component name, component author, component version, dependency relationship, governing license(s), etc.).
- A vulnerability scanner that supports scheduled detection scans and notification schemes (e.g. Trivy, Grype). This tool will schedule automatic scans that identify security issues and provide detailed reports (i.e. risk prioritization, remediation guidance) that help assess the impact to all direct and transient dependencies referenced by your application.
6 Dependency Management Best Practices
The tools above should be augmented by some best practices that can be implemented and enforced through internal policies, processes, and procedures. These six best practices are a good place to start:
- Create a central artifact repository to capture the software inventory with key attributes, notes, and links to additional details in related systems (i.e roadmapping, issue tracking systems, risk management, contracts).
- Define a clear dependency policy that lists acceptable and unacceptable sources and specific approved lists of software components, along with guidelines for gaining approval for components that fill new needs.
- Establish update and upgrade policies that describe the tooling used to scan for dependency vulnerabilities and lifecycle attributes with guidance on how to prioritize, schedule, and apply/defer the scanner's findings.
- Develop a training curriculum to educate developers and others in the organization on the need for ongoing diligence around dependency management and the topics, tools, and techniques required to deliver and maintain a healthy application.
- Adopt a versioning scheme (i.e. semantic versioning) that allows the organization to track the alignment of dependencies to a particular version of an internal application.
- Require formal code reviews and testing that includes a dependency review geared toward heading off the common challenges identified above (e.g. version conflicts – idle bloat).
Final Thoughts
Software has become progressively more complex and the need for speed has driven more code-sharing and reuse. Developers have to rely on available packages to handle solved problems, so they can focus on new challenges that advance their particular mission. And unfortunately, sometimes tracking all the dependencies in those packages gets lost in the DevOps shuffle. Hopefully, this blog offers some actionable steps to make your approach to dependency and open source inventory management a little more sophisticated.
Additional Resources
- Webinar – How to Ace OSS Lifecycle Management
- Blog – SBOM Overview and Your Open Source Options
- Video – Why You Need a Software Bill of Materials (SBOM)
- Blog – Proactive Open Source Lifecycle Management
- Blog - Debunking Open Source Software Security Myths