NuGet/Home

Self-Contained NuGet Packages - License

maartenba opened this issue Β· 56 comments

Update (by @anangaur on 1/8/2019) - Useful links:


Right now, every package can link to a license by providing the licenseUrl property in the metadata. This is awesome, but also not-so-awesome. Allow me to explain my line of thinking.

Every package owner can attach a license to every version of their package. So far, so good, as it allows switching license between versions. So far, so good.

Now imagine utilizing a NuGet package. For impact, let's take Newtonsoft.Json, a very popular OSS package with a permissive license. One day, the author decides to update the HTML contents at the referred license URL. That's... problematic!

Which license applies? The one I read (and agreed with) at package install time? Or the current one that is now displayed on the license URL?

There is no way to figure out the license changed between install and consuming the package, no way to prove it was permissive at time of first install.

Please consider enforcing embedding license info into the package, as the package itself is considered immutable.

I totally agree we should do something about this! A package version's license should be immutable.

Tagging @rrelyea @DoRonMotter

My +1

vbfox commented

Also if licenses are embeeded, please allow authors to simply specify one of the standard OSS licenses ( https://opensource.org/licenses ) instead of a full text.

It'll make blacklisting / whitelisting license a lot simplier and would provide a way to display nicely the package license in the nuget.org UI without guesses in such cases.

@vbfox good idea; imho that should be extended so that you can, for example, filter on named licenses. named only being available when you select one of the standard licenses (all other being custom).

reiz commented

I totally agree. The license name should be mandatory and immutable! On Maven Central (Java) that is the case since years, because of reasons. For license names I would suggest to take the SPDX identifiers, that's a standard for OSS licenses. See here: https://spdx.org/licenses/.

By the way, I'm working on the open source project VersionEye and we did already a lot of work for recognising SPDX identifiers from license URLs provided in Nuget packages.

@reiz We do a similar thing in MyGet. It helps, but ideally license info on a package should be immutable.

reiz commented

@maartenba Absolutely. The license name should be mandatory and immutable. That would make our all life much easier :-) MyGet looks like a nice service.

What happens if I want to change my license to something more permissive? Do I have to create a new package? That could seriously affect branding and visibility.

A new package version in this case, yes.

@JimBobSquarePants Even if the license is more permissive, many organisations have restrictions on what type of licenses they can use. Going from a more restrictive to more permissive might still have legal impacts for those using the packages.

+1

+1. The inability to cite and verify the license that was in effect at the time a package was installed is a considerable weakness in the integrity of the NuGet ecosystem.

@JimBobSquarePants A new version, not a new package. Going from GPL on 1.x to MIT on 2.x, for example.

I don't actually know much about blockchains, but this seems to me to be the sort of thing that could be verified externally with a blockchain, signing and saving something when a package is published.

It could use Project Bletchley.

You don't need a blockchain here because you don't have a distributed trust problem. You have a central authority who can be trusted. They store/serve signed packages with embedded licenses (or links to well known licenses; Universal Resource Identifier style) :)

BTW I suggest googling blockchain, the technology is interesting bit it has become such a hand wavey marketing term. You don't hear the really good technical people talking about it, just the loudmouthed snake-oil salespeople.

In an ironic twist it'll probably turn out that you know more than the people often presenting about the subject (to non technical people) ;)

@maartenba @hhariri @markrendle My bad, misread. Agree with issue.

reiz commented

@JimBobSquarePants A license is always bound to a specific version of a package. Licenses can change from version to version. That's why it's important to track & document licenses in your dependencies automatically. There are different tools out there for this problem. Tools like BlackDuck, WhiteSource and VersionEye. I'm working on the last one, which is completely open source under MIT license.

@rrelyea Some context from my side helping for triage:

  • When analyzing Cordova Apps with its 1000s of NPM (sub)dependencies, standardized SPDX license identifiers inside of the NPM packages helped us to release software using whitelisting/blacklisting. Consider cases like "(MIT OR GPL-2.0)". Without this field, we would need literally weeks to analyze them.
  • License-less and unclear licensed (NPM) packages (e.g. not SPDX compliant statements like "BSD" vs. "BSD-3-Clause" or "MIT*") take serious analysis after identifying them.
  • Micro packages are becoming more and more popular (.NET Core / netstandard). The number of packages will probably grow as well.
  • Do not be late with this topic. During analysis mentioned above, old dependencies with unclear licenses got updated later (during the profesionalization of JavaScript) in newer versions. The old packages are in an unclear state.

I am recommending to enforce a license abbreviation with explicit additional options to "see text embedded in package" or "I hate licensing and do not do it". The first one lawyers need to check and the later can be sorted out automatically. Help with analyzers during the pack phase to ensure that the license is at least clarified.

There's a related issue on the gallery project about license policy (which maybe should be here, or partly merged with this issue).

The main part of it is to be clear about commercially-licensed packages, and ensure there's a clear license link defined -- or simply ban them altogether from nuget.org.

The other part about requiring a project link is partly related to this, and if there's any policy change happening as a result of this ticket that would probably be a good change to go along with it, from a package maintainers point of view.

Thanks for the spec. Everything I hoped for is in it :).
Regards license scanning: I think your new/old friends at GitHub did the same. Maybe connect to them.

For embedded binaries, we've required a LICENSE file and VERIFICATION file since 2015ish for Chocolatey Community Repository. Good to see this come into NuGet proper. πŸ‘

agr commented

I am reading the spec, and the impression I am getting that using SPDX expression and using custom license packaged with a file are mutually exclusive options. Is it expected that users wouldn't be able to do something like "GPL-3.0-only OR MySuperCustomLicense"? Does anyone want to do that?

@agr That's right and by design. "GPL-3.0-only OR MySuperCustomLicense" is by definition a custom license and you should just put that into your license file and point to it.

Hmm - one Point is that "GPL-3.0-only" is a valid alternative choice of "GPL-3.0-only OR MySuperCustomLicense", so someone redistributing it can always choose the "GPL-3.0-only" variant. I think it could be discussed with the SPDX guys whether they want to add some way to express this to their SPDX expression definition.

I got some feedback from the SPDX guys: ("CustomAlternateLicensing" is a placeholder for whatever you choose as the name for the proprietary license).

Referring to Appendix IV: SPDX License Expressions in https://spdx.org/sites/cpstandard/files/pages/files/spdxversion2.1.pdf, then SPDX allows for custom licenses to be named in the format LicenseRef-XXX where XXX is whatever you want to call your license. You could use this to refer to any type of legal text or conditions, whether free, open source or proprietary. Using this you can write a valid SPDX expression such as:

AGPL-3.0-only OR LicenseRef-CustomAlternateLicensing

Appendix V: Using SPDX short identifiers in Source Files describes how you can use these expressions in a source file, for example:

SPDXΒ­LicenseΒ­Identifier: AGPL-3.0-only OR LicenseRef-CustomAlternateLicensing

I'd say this is sufficient to alert a tool to the presence of a custom license, though as there is no defined mechanism to link that LicenseRef to some license text in this context then a tool probably won’t be able to locate that license text automatically. Listing the custom license adjacent to this line or in a separate file alongside is probably the best you can do.

So, "GPL-3.0-only OR LicenseRef-MySuperCustomLicense" is valid SPDX expression, and it makes sense to include the full license terms in a license file within the NuGet package.

Thus, I think it's a valid use case to include both an SPDX expression AND a license file.

@markusshaber good feedback. Know of any real world packages that need to be able to do this?

@karann-msft While there's plenty of software using dual-license models (e. G. MongoDB), I don't have any examples of existing NuGet packages ready.

But maybe @agr has some, as he brought up the topic?

@markusshaber something tells me he doesn't either :)

@karann-msft it would be easy to query for existing NuGet packages if they only had a valid SPDX expression describing their license information in their metadata... :-)

We intent to use dual licensing at https://github.com/SixLabors/ImageSharp.

ServiceStack libraries are covered essentially a dual license but the Nuget packages point to a single license page.

@markusschaber I didn't necessarily mean to limit you to nuget packages only :) (but nuget like ecosystems). In any case, we'll consider it for v2.

@JimBobSquarePants dual licenses are very much supported in the design. What are the two licenses you intend to use for Imagesharp?

vbfox commented

@karann-msft One thing I noticed in the specification is that supported formats are "md, txt" but lot of repository have license files without extensions (It's still pure text) it would be nice for this case to be handled.

For example https://github.com/zeromq/clrzmq/blob/master/LICENSE

@vbfox how about, if the extension is missing, we'll default to "txt" and treat a file without extension as a txt file?

License file inside the package - During the package ingestion, nuget.org will extract the license and host it on nuget.org.

Is the guidance to package the License file in the root of the package? Where will nuget.org look?

Unpacking a nupkg, I am curious about the expected placement of LICENSE.

_rels/
[Content_Types].xml
lib/
LICENSE
PackageName.nuspec
package/
tools/

Thanks

@vbfox I'm not a fan of license files without extension - it's hard to open file without extension on some platforms / environments, as the program associations are strictly bound to file extensions on those systems. So I'm in favour of discouraging extensionless LICENSE, README etc. files, and support @karann-msft with his suggestion of converting extensionless files to .txt files.

vbfox commented

@karann-msft Yes I think they should be supported in the source nuspec as they are so common on repositories, but adding the extension in the nupkg would be perfect as it clarify how NuGet servers & clients should treat them

@vbfox @markusschaber - thanks for that feedback. I'll update the spec to call that out.

@dabutvin - if you are using a well-known license, you don't need to put a file. You can just provide the license identifier.
If you have a custom license, then you must pack it as part of the package. The nuspec license metadata field should then point to the license file within the package. That's how nuget.org, as well as the client, will know where to look for it.

@karann-msft can you elaborate on the csproj strategy of it. Will there be a explicit property in it or do we need to fallback to create a custom nuspec?

Awesome. Just a warning: There is a spdx license name called Unlicense which is a real license. A keyword Unlicensed is very close to that.

@tthiery thanks for the heads-up....what would you use instead of "unlicensed"?

Maybe NonSpecified?

Edit: from previous None to NonSpecified. None could be misinterpreted that the package is not licensed at all (which mean different things in different regions I guess).

agr commented

npm uses UNLICENSED, I don't think we should introduce yet another special case. License expressions are case sensitive, so UNLICENSED will always be in upper case and Unlicense will always be in Pascal case, so it would be more difficult to have them mixed up.

The use of "UNLICENSED" by npm is a rather confusing choice IMHO. The SPDX way is simpler and clearer: NONE or NO-ASSERTION. If you adopt SPDX expressions that would make the most sense (disclosures: I am involved in SPDX and I also maintain the scancode-toolkit which is a license scanner so every choices you make here is something that eventually I will have to write code to support whatever new and unique ways you have to express licenses. I also maintain a comprehensive license expression parser)

@pombredanne we plan to not allow deprecated licenses and as a matter of fact, the client will warn on pack and nuget.org will block publishing a package if you use a deprecated license. (excuse the poor choice for an example in the spec)

Shipped in NuGet release 4.9
(which ships in VS 2017 15.9 and .NET SDK 2.1.500 and .NET SDK 2.2.100)

@ karann-msft

we plan to not allow deprecated licenses and as a matter of fact, the client will warn on pack and nuget.org will block publishing a package if you use a deprecated license. (excuse the poor choice for an example in the spec)

Good... but a reminder that deprecation is a moving target as each new version of the SPDX license list may come with new deprecations.

@karann-msft commented on Sep 7 ...

@dabutvin - if you are using a well-known license, you don't need to put a file. You can just provide the license identifier.

Actually if you do not include the license text of most open source license in a package you are creating a non-compliant package as most license texts should be included as a condition of the license. Using only a well known license identifier is not enough and not a substitute for the text in most cases and it certainly lack clarity always. You need that and the text.

For example, take a simple license such as the MIT: including the full text is pretty much the only condition of the license.... so if you do not include it with a binary nuget package, then you are making your downstream users life miserable by shipping a nuget that is immediately non-compliant and eventually not licensed once downloaded.
User redistributing this package will also need in this case to review in details the package and re-include (and re-package as a new nuget ??) the missing upstream license texts to become compliant if they redistribute this..

So excluding texts is a sure way to create a jolly chain mess if you want my 2 cents.

As far as I can see, Debian distributes common licenses in usr/share/common-licenses to avoid duplications of license texts. I'm not sure how they manage to do it in detail, but Debian legal is well known for their "attention to detail"...

@markusschaber indeed. And Debian does this only for a very few licenses that allow such practice... not for MIT licenses for instance. Furthermore, Nuget is not a distro, so you cannot assume that there is some base present

@pombredanne what I meant to say was, NuGet.org does not need the license file if you provide the license expression. NuGet.org will display license information based on the license expression alone.
If the license requires you to include the license text, you should absolutely pack it within the package. You don't need to add metadata to point to the file.

Hello! Could you provide a link to the documentation of the new license element here? It would make things a lot simpler for us newcomers.

Thank you very much.

@webJose Updated the issue description with useful links (including documentation)