Snap license metadata

Currently a client has no method of determining a snap license.

  • snapd has some code for click-through licenses, but I don’t think this has ever been used.
  • The store allows you to choose from a set of standard licenses (it defined it’s own codes for them I think).
  • It was discussed to use a standard naming for licenses like SPDX [1]
  • GNOME Software shows all snaps as having an “Unknown” license [2]

It seems to me we really need to pass through the field from the store through snapd and the Snap metadata. Perhaps the store license format needs to be converted to a standard, or we use what we have.

[1] https://lists.ubuntu.com/archives/snapcraft/2017-January/002746.html
[2] https://bugs.launchpad.net/bugs/1555567

3 Likes

The store now uses licenses defined by the SPDX standard. Multiple licenses can be specified for a snap and they will interpreted as alternative licenses (or-ed together). There are still two custom licenses supported by the store that are non-SPDX: “Proprietary” and “Other Open Source” but mostly for backwards compatibility reasons.

We still need to expose the license information for a snap via the existing search api in the snap’s metadata so that snapd can use this information properly.

I think ideally the snaps should carry somehow their license information in a way that we can summarize, just adding it out-of-band in the store is doable but not ideal

2 Likes

PR to pass ‘license’ field through snapd:
https://github.com/snapcore/snapd/pull/3556

2 Likes

At the Snappy Sprint (London, June 2017) we discussed also supporting a free-form text document in meta/ that would contain license information for proprietary snaps. This would be used instead of the SPDX field in this case. The store / snapcraft would ensure only one of these was set.

1 Like

This looks good conceptually, but if we’re supporting SPDX license expressions (note SPDX itself is much more than that) we should make that a requirement, by parsing the value and enforcing the syntax. That means we need a parser and need to have a good set of positive and negative unit tests validating what works and what doesn’t.

Also, per the agreements in the sprint, we’re going to support these expressions strictly, without the loose semantics that are today accepted in, for example, AppStream licenses. Since we’re starting anew, that’s a good chance to make the data sane.

Clarifying the field validation - we validate the SPDX expression in snapcraft (i.e. pre-upload) and the store (i.e. reject uploads with bad data). We would not validate the field in snapd (expensive to validate this field for every search query).

@niemeyer - does that match what you expected?

@robert.ancell The points above were about snapd itself. If we allow free text to come in, we cannot make use of it as structured data anymore without breaking backwards compatibility.

@niemeyer as far as I can tell snapd doesn’t validate any fields either from the store or from the YAML from a locally install snap; why would the license field be any different? All these fields are expected to be correct as they came ultimately via the store which did validate them.

That’s certainly not the case. Just walk around the snap/ package for a while and you’ll find all kinds of validation.

Ah, found it in an appropriately named snap/validate.go. I’ve added checks to the PR.

What’s the status on specifying the license in snapcraft.yaml? The PR was merged but snapcraft still doesn’t recognise license key.

Issues while validating snapcraft.yaml: Additional properties are not allowed ('license' was unexpected)
1 Like

people are working on it right now :slight_smile:

Indeed, we will start with some docs (if none exist yet). While those are written though, I’d like to know where the expression parser code lives to be able to run it through snapcraft for validation (unless this is something we will relegate to the store itself).

Additionally, since this field did not exist before, what should the behavior be for when it is missing?

FTR, the store is currently using a Python lib to validate SPDX license expressions. The store implementation was checked against snapd license validation code (in Go), using the same tests.

The store allows to change license value in the web UI. By default, when no license is specified (which is always the case when pushing from snapcraft), the Proprietary value is assumed.

That’s somewhat unfortunate. It’ll surely be the source of pain due to incompatible understanding of which licenses are valid, incompatible understanding of which expressions are valid, and potential metadata around them.

This is also incorrect and unfortunate behavior for that exact reason. We’re giving no choice to people but to push snaps labeled proprietary. The store needs to classify an unknown license as such, and once we define how to push custom licenses, which is the last bit missing, we need to block snaps from being pushed into the store unless they explicitly list their licenses, so no more unknowns going forward.

1 Like

I wasn’t aware of this last bit of discussion until just now, and had filed a bug about the license being changeable in the web UI; this came up in discussion of PR#4531 cmd/snap: display snap license information.

It being tunable in the UI sounds fine. It should follow the same pattern we discussed for other textual details of the snap, such as the summary and the description. That is, snapcraft pushes the first revision, and from there on it will only warn if it diverges, and give an command line option to replace it when desired. The store holds the authoritative version of the data, and can change it via its UI.

I disagree about it being editable via the UI, because doing so increases the amount of work we need to do, not only for the snapd core team, but also for the snappy store team, and for our colleagues at canonical and our friends in the community working on integrating snapd into graphical software centres, with no benefit to our users beyond a (imho minor) convenience to our developers.

This is based on my understanding that once a user has accepted (implicitly or explicitly) a license for a software they have installed, changing that license should require they accept it again.

On the snapd side, if a license can change together with a revision, we need to add work to block refreshes that see license changes, and to notify users that this has happened so they can manually approve (implicitly or explicitly) that license change. This of course depends on warnings, and both it and them will result in more work for software centres, but it’s doable (and as I see it most of the client-side work is part of warnings, not part of this use of them).

If a license can change at any moment, and not tied to a revision, however, we need to be able to … deactivate the software until the user approves? We now have put software on their devices with a license they have not had a change to review (even if we were to remove it, which seems heavy handed, what we’re saying is that there will always be a window when the software on their device will have the new license). I think this would be bad. We need to alert the user of this, which means that the software centres need to have a way to alert the user of something that happened just now, which is a whole new workflow different from everything else these software centres are doing.

On the store side, having it editable via the web UI implies that all revisions will have the same license, as AFAIK the store doesn’t support otherwise. As I suspect this is not what we want, there’d be more work for the store here (how much I don’t know, but my understanding is that per-revision user-editable data would require significant rework).

Another reason (or maybe another way at looking at the same reason) this making them dynamic makes me uncomfortable is that if what we’re saying is that yes, licenses are per snap and not per revision, that means publishers can retroactively change the license of a snap. I can think of no example where this is reasonable and valid, and yet we’re taking on a bunch of work to make it doable.