Skip to content
Insights · Engineering

Name the license the build added

A subcontract added a dependency. Name its license, say whether the client may ship it, and remove it without the person who added it.

Scroll
EngineeringOct 20, 202613 min readBy Salman Naqvi, Founder & CEO
Name the license the build added

A subcontract added a dependency, and the product you are about to put your agency's name on will ship with it. Tonight, in a repository you can open without the person who added it, three things. Name the package, including one it pulled in that nobody typed. Name the license, as an identifier and as a text you can open, or write that the text is missing. Say whether a copy of the client's product leaves the building in a way that text would care about, or write that you cannot tell. If you cannot tell, that dependency does not ship. Removing it, or replacing it with one whose text you can read, is something you do yourself. If any of the three needs the author, you have not named a license. You have a line in a lockfile and a person.

A key the build minted is a different object. Revoke the key they minted is a credential you can list, revoke, and prove dead. A license is a permission to copy. Revoking the key does not change the license, and deleting a license header does not revoke the key. The vendor a tool sends the client's text to is before a tool reads client text. That proof is what the vendor keeps. This one is what the package allows you to ship. Opening the diff at all is read their change before it ships. That article ends when you can say what the change does. This one starts when the change contains a package. The questionnaire the client will send is your first security questionnaire. The questionnaire asks. The answer is a name you checked, not a policy you forward. None of this is legal advice. A license is a copyright instrument. Whether it binds this product is a question for the client's lawyer. Tonight's job is to stop shipping a dependency you cannot name.

The rate people quote is a rate on codebases someone already paid to have examined, and it is not your pull request. Black Duck's Open Source Security and Risk Analysis report for 2026, on the page dated March 2026, uses audits conducted between November 2024 and October 2025. The count you can check is 947 commercial codebases, submitted for mergers and acquisitions, regulatory compliance, and internal risk assessment. The same page says those codebases were split into projects and that the work entails nearly 3,000 individual projects. It does not print the integer behind "nearly," so 947 is the denominator you can defend. This is not a random sample of agency repositories, and it is not a probability that the next import is a conflict. Black Duck sells the audit and the tools that produce it. Read 68% as what showed up when a transaction or a compliance question was already live (Black Duck, Open Source Security and Risk Analysis).

The table and the headline are not the same number, and the mean is not the typical tree. Table 10 prints codebases with license conflicts at 68% for OSSRA 2026 and 56% for the 2025 column, a rise of 12 points, which the page calls the largest single-year jump it has recorded. The headline above the table says "two-thirds." 68% is not two-thirds. Two-thirds of 100 is nearer 67, and the page does not print two-thirds of 947 as its own count. Quote 68% of the audited codebases, and treat "two-thirds" as their label for that cell. Mean conflicts per codebase: 104, against 69 the year before. Median: 8, against 5. Maximum: 2,675, against 1,109, which they describe as a 141% increase. The median is 8. A middle codebase in that audited set is nowhere near the mean. One codebase sits at 2,675, and the mean is pulled toward that tail. Do not tell the client the average application has thousands of conflicts. A second row, 59%, excludes component-to-component conflicts. The 2025 cell on that row is a dash. It is a new cut, not a trend. Their definition, in the next section: a conflict is where "the terms of one license are incompatible with the terms of another license in the same codebase, or when a component's license is incompatible with the codebase's intended distribution model."

The maximum is one project, and the license column beside it is not the column for every audit. The page says the codebase with 2,675 conflicts was a large Gradle project. Of 3,235 identified components in that tree, 2,494 (77%) were Apache License 2.0. That 77% is inside that one tree. The page says Apache's terms conflict with several other licenses, and that this produced the large count. Table 11 is a different question: what share of codebases contain a given license at all. MIT 92%, Apache License 2.0 90%, BSD 3-Clause 85%, BSD 2-Clause 74%, ISC 61%, a generic public-domain marker 57%, GNU LGPL v2.1 or later 48%, the Unlicense 47%, Creative Commons Zero 1.0 46%, Mozilla Public License 2.0 45%. "Nearly half" is their label for the 48% LGPL figure. A codebase can appear in several rows, so the column is not a pie and the percentages must not be added. The 90% of codebases that contain Apache is not the 77% of components inside the Gradle outlier.

Most of the tree is code nobody on the subcontract chose by name, and a pairing is not a conflict. The page says 64% of open source components in a "typical" codebase are transitive, pulled in by direct dependencies. "Typical" is their word. It also says this year's average is 1,180 components per application, up 30%, and that an application of that size "has over 695,000 potential component pairings." A pairing is a combination of two components. It is not a conflict. The mean conflict count on the same page is 104. Quote the pairing sentence as their description of combinatorial room, and quote 104 as the conflicts they actually counted on average. A different 68% lives in the age section: 68% of components are older than 24 months, and a table prints 651,222 such components. That 68% is age. The license 68% is a share of codebases. They share a numeral and nothing else. A status note that uses one for the other will be wrong in a way the client can check.

A survey on the same page is a third denominator, and the page does not print how many people were asked. It says that, in Black Duck's supply-chain survey, 76% of respondents check AI-generated code for security risks, 54% evaluate it for intellectual-property and license risks, 56% assess quality, and 24% do all of those. A usage table, sourced to a separate piece titled "Balancing AI Usage and Risk in 2025," prints constantly 13%, frequently 31%, sometimes 23%, rarely 18%, never or not permitted 4%, and unverified or unmonitored 11%. Those six sum to 100, so they are one distribution of a population the page does not size. 13 plus 31 is the 44% the prose calls frequent or constant use. That 44% is not a license rate, and 54% does not share a denominator with the 947 codebases. Do not set them side by side as if they were one study. If you cannot say how many people were asked, you cannot say how surprising 54 is. You can still say the audit of codebases, which does have a count, found a license conflict in 68% of them.

The prior edition is a different base, and it is the one that says a package manager is not the whole tree. The February 2025 release of the previous OSSRA, covering 1,658 analyses of 965 commercial codebases during 2024, said 56% of audited codebases contained license conflicts, 33% contained open source with no license or a customized license, and "only 77% of dependencies could be identified via package manager scanning," with the remainder "introduced to applications by other means, including AI coding assistants" (Black Duck, 2025 OSSRA announcement). The 56% matches the comparison column in the 2026 table. The 965 are not the 947. The phrase "including AI coding assistants" is their suggestion about the unidentified 23% of dependencies, not a measured share that were generated. A scanner that reads the lockfile and stops has, on that earlier audit, missed about a quarter of the dependencies they could find by other means. Your proof is not finished when the lockfile looks familiar.

The license text that makes a name into an obligation is the GNU General Public License, version 3, and it defines its own trigger. The Free Software Foundation's text says to "convey" a work means "any kind of propagation that enables other parties to make or receive copies." The next sentence is the one a hosted product has to read slowly: "Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying." Section 2 says you may run an unmodified program, and that "the output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work." The client's generated answers are not, by that sentence, automatically the program. Section 5 is the condition that frightens people, and it is a condition of conveying a modified version: you must "license the entire work, as a whole, under this License to anyone who comes into possession of a copy." The same section's aggregate clause says a compilation of a covered work with other separate and independent works, which are not extensions of it and are not combined into a larger program, does not cause the license to apply to the other parts. Section 4, for verbatim copies, requires the notices and "a copy of this License along with the Program." Section 6, for object code, requires Corresponding Source as well, and one of its methods is a written offer "valid for at least three years" (Free Software Foundation, GNU General Public License, version 3).

None of those sentences is a finding that this client's product conveys. A site a customer only logs into can sit inside the sentence that says mere network interaction, with no transfer of a copy, is not conveying. A mobile build, a container you hand the client, an installer, a desktop binary, is a different object, because a copy leaves. Write down which object leaves. If you cannot, the dependency does not ship. The SPDX identifier GPL-3.0-only is a name for that text (SPDX License List). The name is not the grant. A lockfile that says MIT, with no file you can open, is the prior edition's missing-license problem wearing a familiar word. Table 12 on the 2026 page sorts examples into permissive, weak copyleft, and strong copyleft, and it says the presence of a strong copyleft license "isn't automatically problematic" and "requires careful planning and legal review." That review is the lawyer. Your review, tonight, is the name, the text, and whether a copy leaves.

Do the three proofs in the repository you administer, before the change is on the branch the client ships. First, the tree. The direct package is in the diff. One transitive dependency is named, from the lockfile or from a scan that does not stop at the packages someone typed. If the tool you have cannot see past the lockfile, write that, and do not treat the lockfile as the list. The 77% figure is why. Second, the text. You can open the license the identifier points at, or you write that the text is missing, custom, or only a comment in a header. "SEE LICENSE" is not a license you have read. Third, the copy. One line: what leaves the building, and whether you can say the text you opened allows that copy without a condition you cannot meet. Conditions you might be unable to meet include notices you have not kept, source you cannot offer, or a whole-work requirement you have not taken to counsel. If the third line is "cannot tell," remove or replace the dependency yourself. Asking the author to "swap it when they can" leaves the tree they wrote.

Three moves that look like a license review and leave the package in the build. Deleting the header so the scanner goes quiet, which removes the notice section 4 told you to keep and leaves the code. Asking the model that suggested the import to "use something permissive," which may add a second package beside the first. Pasting a NOTICE file full of names you did not open. The model-vendor account, the production keys, and the evaluation set are a different root, and they are what to keep when you subcontract AI. A dependency the application compiles is this article. Both can be true on the same afternoon. Cleaning one does not clean the other. Agency engagements of this kind sit under the non-disclosure we would sign with a client, so they are not on this site as case studies. A case study is the wrong shape for a client's tree anyway.

The shape that makes the removal obvious is a product that already ships as a pile of components, with an admin who can change one of them. Gigbase is a workspace that includes authentication, projects, contracts, and an admin dashboard, built as a product someone runs. The page names a stack. It does not include a license audit, a headcount, a duration, or a result figure, and it is not a claim about any package in that stack. The shape is the test: you can point at a component, open its text, and take it out of the build you administer. A process that can only forward the question to the person who typed the import cannot make that split.

There is a version of this afternoon where hiring a license pass is the wrong purchase. The work is not sold, so there is no client-facing tree to stand behind. The client has asked to meet the people writing the code. That is a disclosure decision, and it is when to tell a client you subcontract, not a reason to skip the name or to pretend the package is yours. The room only has a slide. There is no repository to open. The buyer only wants a template of license names with no tree under them. Or the client has already told a lawyer to decide, and what they asked you for is a legal opinion. Hire the lawyer, or let them hire one. A lockfile does not issue opinions, and neither does this page.

Where the change is real and the repository is yours, the work is the name, the text, and the line about whether a copy leaves, done before you tell the client the build moved. A white label software development partner that expects this will put the repository in your organization and the license name on the review, before the first week is billed, because reading the identifier is part of reading the diff. One that can only offer a status line is telling you who is allowed to choose what the client ships. Where the next slice is a single capability, an AI integration sprint is the shape that can require this name as the definition of done, rather than as a surprise in a questionnaire. The accounts that had to be yours before you could open the tree are the handover. If you cannot yet open it, you are not behind on a spreadsheet. You are about to sell a dependency you have not read.

Before the branch ships, write the three lines. The package, including one nobody typed. The license text, or the fact that it is missing. Whether a copy leaves, and that you removed the dependency if you could not say. Do not delete a header and call the scanner's silence a review. The lockfile is how you notice the name. The text is the page you can hand a lawyer. The line about the copy is the one that decides whether it ships tonight.

The version that lockfile resolved, as opposed to the license text on the package, is name the package the lockfile pinned. A name without a version is this page. A version without the text is that one.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→