When you ship a program that uses open source code, you need to make sure that 1) your licensing is compliant, and that 2) you provide the necessary attribution, licensing, and (possibly) source code for the open source components you use. But many people are confused about how far back their disclosures need to go. Do you need to declare every dependency, including dependencies of dependencies? What do you need to share?
The Problem: Dependencies and transitive dependencies
To understand the rules, we first have to define the problem. Software applications generally have a lot of subsystems and other components. Many times, the components that your software uses are third-party open source code. These are sometimes called "libraries" or "modules," but those are just different names for a bunch of related functions that are grouped together into a component. This modular approach allows developers to leverage existing code and functionality without reinventing the wheel. By incorporating external components, developers can benefit from tested and optimized solutions, streamlining the development process and improving software quality.
Your software application directly uses some of these components. Sometimes these components are compiled-in, becoming part of the same executable program on disk. Sometimes these components are "linked" in, loaded into memory and integrated into your program as it runs. For some languages, like Python or JavaScript, these components are never directly integrated together, but instead are "imported" and used at runtime.
Components that are directly used by your software are referred to as "direct" dependencies, or sometimes just "dependencies." These components can in turn have their own dependencies. These are called "transitive" dependencies. Your software still relies on these transitive dependencies through an indirect chain of dependencies.
How to bundle a dependency with your application
Sometimes it makes sense to bundle copies of open source components with your application. It could be that those components are tightly integrated into your application, or perhaps that having some of the dependencies bundled and configured correctly makes installation easier and more convenient. This bundling is sometimes referred to as "vendoring" a component.
If you are vendoring a component, best practice is to put your code in a directory named "src" and each vendored component into its own named subdirectory within an overall third-party component directory. For example, if your software includes a copy of "libfoo 1.2.3", the directory structure would look like this:
/src
[Your code...]
/third-party
/libfoo-1.2.3
libfoo.py
LICENSE.txt
[etc...]
The subdirectory should include a copy of the entire project, including its LICENSE file and any other information that is included with the open source component.
What to put in your LICENSE and NOTICE files
When a component is shared under an open source license, you are required, at minimum, to provide attribution and a copy of the applicable license. Sometimes licenses like the GPL require that you share source code as well. But how much is in scope? Just your code, your direct dependencies, or all dependencies, even transitive ones?
There are a couple of simple rules of thumb. First, your LICENSE file (usually named LICENSE.txt) should only include the license information for your application. If the license for one of your dependencies is a reciprocal license (such as the GNU GPL), then it may require that the license for your code also be under the same GPL license. However, the LICENSE file should only refer to the code that you are licensing out.
Second, your NOTICES file needs to list every component that is shipped with your product - either directly integrated or vendored. If you distribute a component, you are required to declare it and include a copy of its license. We also suggest including a copy of the source code by default as it makes compliance much simpler.
The Prometheus project has a particularly nice NOTICE file that you can emulate.
What about transitive dependencies?
Here is where people can get confused. You generally don't need to include transitive dependencies in your NOTICE file. That is for only the open source components that you are directly distributing to others.
But transitive dependencies can affect what you put in the LICENSE file. If one of your transitive dependencies is under a license like the GPL, then it might force all your code to be under the GPL (or at least a GPL-compatible license). Understanding whether a GPL'd dependency has that effect is fact-dependent and requires a knowledgeable analysis.
Further, transitive dependencies directly implicate the security of your application. Given the updated requirements for government contracts,, you will need to include them in the full SBOM (software bill of materials) for your application.