Snap license metadata

You are thinking about the implementation. I’m thinking about the publisher and the user.

Option one, with license in snap and field in the store

How it works:

You need to set the license in the snap, and in the store.

Consequences:

  • When is the data updated?
  • Who updates it?
  • What happens if it is updated?
  • What if it is not updated?
  • Why is my software showing no license if I have updated it in the store?
  • Why is snap A showing the license of edge while B shows the one of stable?
  • Why is my software showing a different license if I updated it in the store?

Option 2, with license in snap only

How it works:

You set the license in the snap.

Consequences:

  • When is the data updated?
    You’ve built the snap with it.

  • Who updates it?
    You’ve built the snap with it.

  • What happens if it is updated?
    You’ve built the snap with it.

  • What if it is not updated?
    You’ve built the snap with it.

  • Why is my software showing no license?
    You’ve built the snap with it.

  • Why is snap A showing the license of edge while B shows the one of stable?
    They don’t.

  • Why is my software showing a different license?
    Yes, that’s still an issue. It will always be no matter what we do, because we cannot reasonably show every license of every revision at once when presenting the store generally. Thus, heuristics pick a sensible one when we have no context.

1 Like

While working on some documentation and examples I tried to include license in a new snap I made. I noticed that snapcraft doesn’t allow the license field defined at the top-level.

snapcraft --version
snapcraft, version 2.34+17.10

The error message I got was:

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

The snapcraft.yaml contained license: MIT

1 Like

@sergiusens :arrow_up:

We removed that almost 2 years ago and were waiting on the validation tool to add again (as discussed in Warsaw). Are we saying we now want the field and to allow for non-validated entries?

We could expose a license validator from snap internal, would that help you in snapcraft (it could also be used by the store, perhaps)

@zyga-snapd If snapcraft is using, that’s not very internal, so we may as well make it into a proper public command line API.

@sergiusens I think what we’re saying is that it’s time to revisit this topic and move things forward.

I guess @snapcraft was meant to be @sergiusens (I hope I am not considered the tool that I am and correlated with the tool I work on :slight_smile: ).

I would really like to get this sorted, I just want to do it the right way or at least make it a conscious decision that we would take a shortcut (not necessarily saying that we are).

This snap command, or whatever it ends up being, would need to be supported on Mac and Windows, we can take care of building it and testing, but should be build-able. An isolated command would ease the burden for this. We could write a small shim ourselves but it might be better if you guys take care of it to keep the possibility of refactors for the underlying code that does the checks.

@sergiusens Sorry, yes, I meant Mr. Snapcraft. :wink:

Alright… let’s get it sorted in snapd first, by introducing a validator command line option, and we can then bother you again to introduce the field.

It’s unclear from the above whether a consensus was reached and work is ongoing, or if we’re stuck. Could you summarise where we are on this?

1 Like

Nudging this topic to see if any further decisions have been made…

Why not support AppStream in general? That would not just handle the licensing use case but also a lot more metadata required by the store. I flound it an annoying PITA to separately manage the store metadata when I already had everything in the AppStream file.

The idea was for snapcraft to read existing AppStream files in the upstream source and use that metadata, but it’s not implemented yet.

Also, snapcraft still needs to support projects not using AppStream. Indeed, part of the point of this thread is designing how that’ll work generically in a way that can also acommodate getting metadata from AppStream files.

Cheers,

  • Daniel
1 Like

This thread is a bit tangled, I’ll try to summarize what’s been discussed so far and scope the thread to have a clearer picture. For reference, an index of the threads discussing licensing topics is at the top of this post on another thread. I apologize if there’s a proliferation of threads on licensing: it’s a complex topic that involves several components and encompasses several user stories and I think by discussing each more narrowly we stand a better chance of designing this in a way that will satisfy everyone’s needs. That said, if anyone feels we should consolidate some of these threads, please let me know.

General proposal for license handling

Gustavo and John made a proposal contained in 2 earlier posts on this thread:

  1. snaps will have a license field - the field name is discussed in Accept license field in snapcraft.yaml. Is there another thread regarding the required changes in snapcraft and click-reviewer-tools? If not, I would suggest a separate thread which can talk about aspects mentioned here, such as validation with a tool provided by snap itself and other related things.
  2. Implement the described logic in the store - I think we can scope this thread to this point. This kicks in once a snap with a license has been uploaded and validated by the click-reviewer-tools.
  3. Support custom licenses is discussed on Support for custom license text
  4. Change snapcraft to warn about missing licenses - Probably bears separate discussion as well, it might be good to postpone this until the previous steps are done, because if we don’t have a usable “this happens when you set a license in your snap” story, publishers will be confused. In any case this is much more clear-cut.
  5. Change the store to reject new snaps without licenses after a grace period is also pretty clear-cut and as Gustavo mentioned, it can only happen once snaps with licenses are flowing nicely into the store.

Specifics on how to store and present the license in the context of a single snap

For item 2, the common aspects are:

  1. Incoming snap uploads should have a license: field.
  2. The store stores the license data per revision.

Then we have two different proposals for where to get the license for the snap (the difficulty to solve here is that several revisions for the same snap may have differing licenses).

John and Gustavo propose the snap’s licensing data, as contained in each uploaded revision, as the sole authoritative source. There would be a store-side heuristic (to be refined), which when asked about the license for the snap, will give the license for the most stable channel for which there is something released for this snap. Thus, if there’s something in latest/stable , the license for that revision will be shown. If not, but there’s something in latest/edge, then that’s what’s shown. Difficulties pointed out with this approach:

  • The heuristic adds complexity to both documentation and code.
  • Because of channel map constraints (arch, validation, epochs, etc), the snap could expose a (dynamically calculated) different license. The heuristic may need to take this into account so the results are consistent, and designing this behavior is a given if we decide to go the heuristic way.

Bret suggested using the existing metadata workflow to modify the license. That is:

  1. a snap-level “license” database item would exist in the store and be updated with the contents of the license: field in the .yaml every time a snap is pushed.
  2. The usual metadata rules for conflict resolution and forcing updates via snapcraft would apply.
  3. In principle this allows keeping the existing web UI for updating the license (with conflict handling per the above), mainly for consistency with other metadata.
  4. This is the license presented to the user when asking about the license for the snap.

Shortcomings with this approach:

  1. makes people think that just having a license set in the store is enough to give their snaps a license. It’s not.” This was put quite clearly by Gustavo so I quoted him :slight_smile:
  2. Two places to set the license, which may be a problem even with the conflict resolution properties of metadata, given the nature of licensing data.
  3. the license is tightly bound to the snap content”. A compelling reason for not allowing editing of the license out-of-band.

So in order to move this now narrower topic forward, I think we could focus on discussing and choosing one of these two approaches, or maybe design another one which takes these concerns and desirable properties into account. Even if this is only a starting point for a discussion to be had later.

Other things

We’ve already mentioned that the license presented for an installed snap is that of the installed revision, which is unique and non-ambiguous.

Another aspect that was discussed in this thread is what happens when the license changes and how to notify the user which spills into the general topic of responsibility for presenting the license and gathering acceptance from the user. As mentioned in Support for custom license text, “Deciding when and where we show the license to the user for acceptance. It sounds like we’ve discussed that before but I didn’t find any relevant topics. If there are none, I would prefer starting a new one. This has implications as to whether the store needs to keep a copy of the custom license, or just needs to indicate that there is a custom license and that it’s contained in the snap, but those can be discussed in the other topic.” Other related implications raised in this thread include the need to keep a time/date of last license modification, and whether by not notifying the user we expose them to being in violation of a non-accepted license.

1 Like

Thanks for the clear summary of this discussion @roadmr. I’m here to poke this topic and see if there has been any movement as i’m designing the License field for snapcraft.io.

Dashboard currently allows the license to be set in the store, which we can point users to until the snapcraft.yaml accepts a license field and/or we reach a final conclusion on this topic.

Hi Greg,
We haven’t yet discussed the mentioned approaches and/or chosen one, so for now I think what you can do is this:

Currently, the same API that allows setting metadata such as summaries, descriptions and icons also supports setting the license (and modifies what is currently a per-snap value), so there should be no need to point users to the store dashboard, assuming you’re OK with doing frontend work for a feature which may well change if/when it is decided to manage the license data per-revision instead of per-snap.

API documentation should be here, the required value for license is an SPDX expression (which the store validates properly prior to storing, so if it’s bogus you’ll get a nice error message).

Similarly, at the moment the single per-snap license value is what should be presented. In any case, if we go forward with the per-revision license information, the implication of having store-side heuristics is that when queried for “what’s the license of this snap?” we would still return a single value, so for presentation purposes your end shouldn’t change that much.

Let me know if this makes sense or if you need more information!

Cheers!

  • Daniel

This makes sense.

Thanks very much