How To License Open Source Code Properly

anonyco

Jack Giffin

Posted on December 15, 2022

How To License Open Source Code Properly

(This article is pending review/edits by a lawyer. As always, this article and the information herein is provided WITHOUT ANY WARRANTY and is provided without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. So, only use this article as a starting point and never use this article as a substitute for a lawyer.)

Many open-source software projects only add a LICENSE file and stop there. This quick-and-dirty approach to licensing software is okay and certainly much better than no license or brief mention of the license in the README, but it can leave much to be desired in the event of legal scrutiny.

Even for trivial projects, it's vital to always exercise due diligence with licensing. The law does not follow common sense—the law may superficially appear to follow common sense as many laws are created with common sense in mind—and it's much better to proactively bulletproof everything than to deal with the ensuing mess in the unlikely event of a legal matter. Oftentimes, it's not even the software creator/copyright-holder who suffers but a user of your software, and I imagine you wouldn't want to jeopardize the users of your software.

A Primer/Introduction On The GNU GPL

For those unfamiliar with the GNU GPL, let me elucidate the ironic contrast between the extreme simplicity of the GNU GPL and the many many pages of text it takes to legally enforce it.

The GNU GPL can be summarized down to one statement: enforce that every successive recipient passing your software forwards inherits all the same rights/abilities for what they can do with the software. A crucial implication of this definition is that certain freedoms—particularly, the ability to distribute your software closed-source—are restricted in order to safeguard the propagation of other freedoms—particularly, access to the source code. So, to spell it out in more words, every aspect of the GNU GPL centers around enforcing the 4 basic software freedoms everyone should have:

The 4 essential software freedoms: to run when/where you want, to study how it runs, to give/sell, and to give/sell derivative works
(Source: https://www.gnu.org/graphics/amihud-4-freedoms.html)

Permissive licenses like the MIT, Apache, CC0, and Unlicense all fail to enforce that any of the software freedoms propagate forwards to the end users at of the software (because, for example, permissive licenses allow inclusion in closed-source software, and the recipients of that closed-source software don't enjoy the software freedoms.) These permissive licenses encourage unjust exploitation of the software with incorporation/adaption into closed-source business software. And, it doesn't stop there. Catalyzing the spread of closed-source software has significant ramifications further down the line where it's abused to force users (especially business users) to pay exorbitant fees for continued access to their content, it's used as a fear-tactic to trick users into thinking they need useless software (the scam that is anti-virus software), and it's used to lock customers in and prevent them from switching to a different solution (vendor-lockin).

So, why is the GPL so long? Because the court of law doesn't care about common sense (because common sense is debatable as it is not written down anywhere); every condition and contingency must be laid out in plaintext. For example, there's a ton of text explaining how GPL software can't be used in permissively licensed software (instead, it must be combined and the combination of GPL+permissive must be GPL-licensed). To explain, allowing GPL code to be used in non-GPL code would lead to the situation of, for example, adding a MIT-licensed helloworld.c file to a GPL-licensed project and calling the resulting combination project MIT-licensed to bypass the GPL. It's simply not possible to objectively lay down an all-encompassing bulletproof list of rules for where to draw the line between allowing GPL usage in permissive software and not allowing its usage, which is why the GPL must default to the only objective option available, which is to forbid any usage of GPL code in non-GPL code. (Actually, there is one way to draw the line—shared object file linking—and the LGPL/Lesser-GPL permits LGPL-software's inclusion in proprietary/permissive software only in this way. However, the LGPL is problematic as it encourages closed-source/permissive software, so try to avoid LGPL usage.)

On the other end of the spectrum is the AGPL/Affero-GPL, or, as I like to call it, the Awesome GPL. The AGPL is the same word-for-word as the GPL except that the AGPL adds a section expanding the scope of the user/customer of the software to anyone interacting with the software over a network. This addendum closes the SaaSS—service as a software substitute—loophole. For example, this website, dev.to, is AGPL software: https://github.com/forem/forem. As Forem demonstrates, the AGPL has a convenient ace up its sleeve— anti-competitive retaliation—which means that a competitor would be unsuccessful trying to start a competing business using Forem's source code because dev.to is already established and Forem will be able to request the source code for their competitor's fork (either directly by becoming a paying customer of their competitor or indirectly by paying a 3rd party to become a customer) and take all of their competitor's improvements/features. (Actually, a competitor could be successful if Forem stopped caring about its users and mistreated its customers, as its customers would then prefer switching to the same-software different-business competitor. And, users would be able to painlessly switch because the GPL guarantees the inspectability of the source code, so there's nothing Forem could do to prevent its competitor from developing software to ease users' migration to its system.) Libraries should not be licensed under the AGPL because it can needlessly complicate matters for certain projects. For example, if you have a super complex CI/CD system deeply integrated with an AGPL-licensed HTTP server, then you have to figure out some way for users visiting the website to run the AGPL HTTP server on their computer if they request source code, which could be a doozie. Always remember that the mission of the GPL is to promote software freedom, not to be a pain in the ass to deal with.

For further reading on the GPL, I highly recommend reading through https://www.gnu.org/licenses/license-compatibility.html and https://www.gnu.org/licenses/gpl-faq.html.

Licensing Steps

Now that we understand the GNU GPL, let's dive into how to apply it to our project. The following overview comes straight from the horse's mouth:

  • Get a copyright disclaimer from your employer or school.
  • Give each file the proper copyright notices. Make sure to clearly identify which versions of the license users can use.
  • Add a COPYING file with a copy of the GNU GPL or GNU AGPL.
  • (If using the LGPL, which is discouraged) Also add a COPYING.LESSER file with a copy of the GNU LGPL.
  • Put a license notice in each file.
  • (Optionally) make the program display a startup notice.
  • (If using the AGPL) make the program offer copies of its source code.

Hot links to the license files:

Please continue reading as the process is not as straightforward as the simple list above might lead you to believe.

Giving Files Copyright Notices

Even this detail is not as trivial as it may seem as Richard Stallman recommends expressing explicit support for both your chosen version of the GPL and additionally any later version (read https://www.gnu.org/licenses/identify-licenses-clearly.en.html):

/* SPDX-License-Identifier: GPL-3.0-only or GPL-3.0-or-later */
/*
 * Brief description of the software written in C or C++ or
 *  or C# of Rust or Node.JS or a million other languages.
 *
 * Copyright (C) 2023 Your name <email@address.com>.
 * 
 * This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
// code...
Enter fullscreen mode Exit fullscreen mode

For other comment styles and files prefixed with a shebang, put the notice text immediately after all necessary lines at the top of the file:

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-only or GPL-3.0-or-later
#
# Brief description of the software written in C or C++ or
#  or C# of Rust or Node.JS or a million other languages.
#
# Copyright (C) 2023 Your name <email@address.com>.
# 
# This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.

# code...
Enter fullscreen mode Exit fullscreen mode

Dual-License Your Software

There are many cases of software that interacts closely with—yet independent of—other separately licensed (potentially proprietary) software, and any offered example snippets/peeks of the other software side are themselves licensable software. If these snippets are licensed under the GNU GPL, then usage of these snippets would be subject to the full terms of the GNU GPL, so it's important to analyze the context of usage of these snippets and decide whether to dual-license the snippet under permissive licenses. If you are unsure, then it's likely that your software does not need this extra work done; very little software needs this. Nobody cares about how these small snippets are used, so there's no harm in removing all possibilities of legal liability.

My proposed solution for this problem is to create a README-snippets.md file which contains all the code snippets from the README and is dual-licensed under the all-permissive BSD 0-clause license (see 0BSD on SPDX).

First, create a section in your README.md explaining the licensing structure for your project.

<!-- Example section in README.md -->
### Licensing Structure

This project has a complex licensing structure defined by the following rules in order from lowest priority to highest priority.
1. By default, all files are licensed under SPDX either GPL-3.0-only or GPL-3.0-or-later. See the `LICENSE` file for more information.
2. The `README-snippets.md` file is additionally provided under the SPDX 0BSD license. See the [0BSD license](README-snippets.md#0bsd-license) section of the README-snippets.md for the license text.
<!-- more points about licensing structure as needed... -->

Enter fullscreen mode Exit fullscreen mode

Second, create the README-snippets.md file containing a dump of all your documentation's code snippets and license it under the 0BSD license.

<!-- Example contents of README-snippets.md -->
<!-- SPDX-License-Identifier: 0BSD or GPL-3.0-only or GPL-3.0-or-later -->

### Code Snippets Dump

This page is a dump of all the code snippets in the documentation licensed under the BSD 0-clause license so that you may freely use these snippets for any and all purposes.

\`\`\`
uint32_t popcnt32(uint32_t x) {
    x = (x & 0x55555555) + (x >> 1 & 0x55555555);
    x = (x & 0x33333333) + (x >> 2 & 0x33333333);
    x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
    x = (x & 0x00ff00ff) + (x >> 8 & 0x00ff00ff);
    x = (x & 0x0000ffff) + (x >> 16 & 0x0000ffff);

    return x;
}
\`\`\`

<!-- dump more snippets... -->

### 0BSD License

This project is _primarily_ (not exclusively) licensed under SPDX either GPL-3.0-only or GPL-3.0-or-later. A copy of the BSD 0-clause license is provided here only for this file to be licensed under the SPDX 0BSD license. See the [Licensing Structure](README.md#licensing-structure) in README.md for an authoritative explanation of the licensing structure of this project.

> BSD Zero Clause License
> 
> Copyright (C) YEAR by AUTHOR EMAIL
> 
> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
> 
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Enter fullscreen mode Exit fullscreen mode

This way, in the event of litigation of one of the users of your software, the user can claim they got the snippet code from the all-permissive README-snippets.md file under the BSD 0-clause license, which should quash any dispute.

If you have a more complex organization of documentation than just stuffing it all in your README, then it would probably be best to create a special documentation page where you dump all of your code snippets and license that documentation page under the BSD 0-clause license.

Emphasize that this extra work is rarely needed, as explained in the first paragraph of this section. Typically, only CLI software such as a script interpreter might need this README-snippets.md workaround.

Advertising the GNU GPL license

It would be considerate of you to advertise that your software is licensed under the GNU GPL (and which GNU GPL) at the top of your README with logos. This mitigates the possibility of users accidentally using your software in contexts such as developing proprietary software where it can't be used.

|![gplv3-only](https://www.gnu.org/graphics/gplv3-with-text-136x68.png) |![gplv3-or-later](https://www.gnu.org/graphics/gplv3-or-later.png)|
|-|-|

# This is The README header for the project
Enter fullscreen mode Exit fullscreen mode

Here's what that looks like:

gpl-v3-only gplv3-or-later

This is The README header for the project

Displaying Licensing Information At Startup

Whether you need to publish licensing information greatly depends upon the scope of your software:

  • If you are writing a library, you shouldn't publish or provide any APIs for licensing information; a library should be submissive and obedient, not vociferous and overextending.
  • If you are writing a GUI application, then just show the license as part of the "About This"/"Info" menu. (And, it's considered best-practice to also provide the user with a pop-up where they can read a locally-stored copy of the entire GPL license):

    Copyright (C) <year>  <name of author>
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    
  • If you are writing interactive CLI software, then produce the following text at startup. If you are unsure whether your CLI software is interactive, then I can guarantee it's not interactive.

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type 'show c' for details.
    

    You would need to modify 'show w' and 'show c' to reflect the commands you provide with your interactive CLI. The 'show w' or 'show warranty command prints sections 15-17 of the GNU GPL license (from gpl-3.0.txt or whichever version of the GPL you are using.) The 'show c' or 'show copying' command prints the full text of the GNU GPL license.

  • If you are writing non-interactive CLI software, then the most common behavior is to show the license as part of the --version long-hand argument:

    ~$ gzip --version
    gzip 1.10
    Copyright (C) 2018 Free Software Foundation, Inc.
    Copyright (C) 1993 Jean-loup Gailly.
    This is free software.  You may redistribute copies of it under the terms of
    the GNU General Public License <https://www.gnu.org/licenses/gpl.html>.
    There is NO WARRANTY, to the extent permitted by law.
    
    Written by Jean-loup Gailly.
    

    Some programs additionally provide --license, such as gzip, though this is not strictly mandatory:

    ~$ gzip --license
    gzip 1.10
    Copyright (C) 2018 Free Software Foundation, Inc.
    Copyright (C) 1993 Jean-loup Gailly.
    This is free software.  You may redistribute copies of it under the terms of
    the GNU General Public License <https://www.gnu.org/licenses/gpl.html>.
    There is NO WARRANTY, to the extent permitted by law.
    

Inform your users so they know their rights

The GPL can be quite scary as it's often chalked up to be some humongous complicated "viral" license and this can sometimes scare people away. So, I always try to include a quick short blurb hitting the most relevant/important aspect(s) of the GPL and how they apply to this particular software project. That way, users of my software can both see how benign the GPL is and they can know how to properly use my software without getting into legal trouble.

Listed below are some example blurbs you can copy and paste into your README depending on the type of software you are developing.

  • Example blurb for software libraries:

    ### The GNU GPL/General-Public-License
    
    <YourLibraryName> is free and, more importantly, libre software, being licensed under either GPL-3.0-only or GPL-3.0-or-later, which secures the rights of end users of software incorporating <YourLibraryName>.
    
    **Notice:** This library can _only_ be used in GPL-licensed software. So, for example, your software must be licensed under version 3 or later of either the GPL or AGPL licenses in order to incorporate this GPLv3 or GPLv3-or-later library.
    
    Below is a copy of the legally-binding disclaimer you implicitly agree to by using this software.
    
    > This program (<YourLibraryName>) is free software: you can redistribute it
    > and/or modify it under the terms of the GNU General Public License as
    > published by the Free Software Foundation, either version 3 of the
    > License, or (at your opinion) any later version.
    >
    > This program is distributed in the hope that it will be useful,
    > but WITHOUT ANY WARRANTY; without even the implied warranty of
    > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    > GNU General Public License for more details.
    >
    > You should have received a copy of the GNU General Public License
    > along with this program.  If not, see <https://www.gnu.org/licenses/>.
    
  • Example Blurb For interpreter/compiler/scripting-language software:

    ### The GNU GPL/General-Public-License
    
    <YourInterpreterName> is free and, more importantly, libre software, being licensed under either GPL-3.0-only or GPL-3.0-or-later, which secures the rights of end users of software incorporating <YourInterpreterName>.
    
    **Notice:** The *GPL-3.0-only or GPL-3.0-or-later* license only applies to the script interpreter. The code in the scripts you execute with this software is independent of and abstracted from the GNU GPL license, so this software may be freely used to run script files of any license. Only modifications to this software itself involve the GPL license.
    
    Below is a copy of the legally-binding disclaimer you implicitly agree to by using this software.
    
    > This program (<YourInterpreterName>) is free software: you can redistribute it
    > and/or modify it under the terms of the GNU General Public License as
    > published by the Free Software Foundation, either version 3 of the
    > License, or (at your opinion) any later version.
    >
    > This program is distributed in the hope that it will be useful,
    > but WITHOUT ANY WARRANTY; without even the implied warranty of
    > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    > GNU General Public License for more details.
    >
    > You should have received a copy of the GNU General Public License
    > along with this program.  If not, see <https://www.gnu.org/licenses/>.
    

    (Notice: this gets tricky because it becomes problematic where your GPL interpreter software ends and where the user's potentially proprietary software ends. In this case, it's best to license the standard library of your scripting language under the GNU LGPL license and write a formal specification of your scripting language to shift the perspective towards the user writing their scripts to target a general language specification, not a GPL-licensed language implementation)

  • Example Blurb For Interactive/GUI Software

    ### The GNU GPL/General-Public-License
    
    <YourGUISoftwareName> is free and, more importantly, libre software, being licensed under either GPL-3.0-only or GPL-3.0-or-later, which secures the rights of end users of software incorporating <YourGUISoftwareName>. The main implication of this license is that pieces of code taken from (even if modified) <YourGUISoftwareName> cannot be used in non-GPL-licensed software. However, GPL-licensed code can still be combined with non-GPL code if the licenses are compatible (visit [https://gplv3.fsf.org/wiki/index.php/Compatible_licenses](https://gplv3.fsf.org/wiki/index.php/Compatible_licenses)) license and you license the resulting software combination under GPL-3.0-only or GPL-3.0-or-later (preferably both.)
    
    **Notice:** The GPL has no effect on you unless you delve into this project's source code. So, use this software freely for whatever purpose. Just make sure to read up on the GPL if you delve into the source code.
    
    Below is a copy of the legally-binding disclaimer you implicitly agree to by using this software.
    
    > This program (<YourGUISoftwareName>) is free software: you can redistribute it
    > and/or modify it under the terms of the GNU General Public License as
    > published by the Free Software Foundation, either version 3 of the
    > License, or (at your opinion) any later version.
    >
    > This program is distributed in the hope that it will be useful,
    > but WITHOUT ANY WARRANTY; without even the implied warranty of
    > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    > GNU General Public License for more details.
    >
    > You should have received a copy of the GNU General Public License
    > along with this program.  If not, see <https://www.gnu.org/licenses/>.
    
  • Example Blurb for CLI Software and Software that generates files.

    ### The GNU GPL/General-Public-License
    
    <YourCLISoftwareName> is free and, more importantly, libre software, being licensed under either GPL-3.0-only or GPL-3.0-or-later, which secures the rights of end users of software incorporating <YourCLISoftwareName>. The main implication of this license is that pieces of code taken from (even if modified) <YourCLISoftwareName> cannot be used in non-GPL-licensed software. However, GPL-licensed code can still be combined with non-GPL code if the licenses are compatible (visit [https://gplv3.fsf.org/wiki/index.php/Compatible_licenses](https://gplv3.fsf.org/wiki/index.php/Compatible_licenses)) license and you license the resulting software combination under GPL-3.0-only or GPL-3.0-or-later (preferably both.)
    
    **Notice:** The *GPL-3.0-only or GPL-3.0-or-later* license only applies to this software. The files you create using this software are your own original works, subject to your copyright and whatever purpose/license you choose.
    
    Below is a copy of the legally-binding disclaimer you implicitly agree to by using this software.
    
    > This program (<YourCLISoftwareName>) is free software: you can redistribute it
    > and/or modify it under the terms of the GNU General Public License as
    > published by the Free Software Foundation, either version 3 of the
    > License, or (at your opinion) any later version.
    >
    > This program is distributed in the hope that it will be useful,
    > but WITHOUT ANY WARRANTY; without even the implied warranty of
    > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    > GNU General Public License for more details.
    >
    > You should have received a copy of the GNU General Public License
    > along with this program.  If not, see <https://www.gnu.org/licenses/>.
    

Addendum: Using Code from StackOverflow

All code snippets on StackOverflow are licensed under the latest version of Creative Common's CC-BY-SA license (currently v4.0 here). When using StackOverflow, it's crucial to always cite the StackOverflow post:

// popcnt32 was adapted from https://stackoverflow.com/a/14010273/5601591 
uint32_t popcnt32(uint32_t x) {
    x = (x & 0x55555555) + (x >> 1 & 0x55555555);
    x = (x & 0x33333333) + (x >> 2 & 0x33333333);
    x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
    x = (x & 0x00ff00ff) + (x >> 8 & 0x00ff00ff);
    x = (x & 0x0000ffff) + (x >> 16 & 0x0000ffff);

    return x;
}
Enter fullscreen mode Exit fullscreen mode

It's that simple. Make special note of the fact that I extensively modified the function to the point where it no longer resembles the one I got from the StackOverflow answer. Those modifications don't matter; I used the StackOverflow answer as a starting point, it doesn't harm anything to cite the StackOverflow answer, and it alleviates any legal ramifications. For example, there might be a CCTV camera recording what I'm doing.

💖 💪 🙅 🚩
anonyco
Jack Giffin

Posted on December 15, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related