└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # yogslaw 2 | 3 | ## What is this? 4 | 5 | This is a thought experiment for a potentially different "default approach" to software licensing of my Open Source Projects. I'm not proposing you do this: but rather thinking out how I could do this. 6 | 7 | Some of my projects have reached a level of use in the Rust ecosystem, including some commercial usage. To date, I've not received (or requested!) funds for these libraries, but also have never been hassled by my users for support or unreasonable requests. 8 | 9 | ## Background 10 | 11 | This was originally written in the aftermath of the `log4j` vulnerability, and the discussion that resulted from the lack of financial support for the authors and maintainers. 12 | 13 | The name comes from writer Jim Macdonald's "Yog's Law", who reminded writers that **"Money flows toward the writer."**. This was suggested (indirectly) by [Naomi Wu](https://twitter.com/RealSexyCyborg/status/1470044032290402307) on twitter. 14 | 15 | ## What are my goals? 16 | 17 | In my open source projects, I aim to: 18 | 19 | * Share my projects with people to see, learn from, be able to debug. 20 | * Make clear what other people's expectations should be (regarding support, change requests, security updates, maintenance) for code I write: namely none, unless otherwise agreed. 21 | * Allow generally unrestricted use for non-commercial users 22 | * Set the expectation that **if people derive monetary benefit from the code I write: I expect to be paid for it.** 23 | * Provide an easy, low-hassle way to pay for additional support and increased maintenance expectations 24 | 25 | ## What are **NOT** my goals? 26 | 27 | In my open source projects, I don't generally care about the following: 28 | 29 | * I am not interested in making my code "as widely usable/used as possible", at least not with this approach. 30 | * I am not interested in worrying about making code that is "incompatible with commercial usage", at least at the "free" tier 31 | * I don't particularly care if my approach is compatible with existing OSI or FSF paradigms 32 | 33 | ## How do I (think) it would work? 34 | 35 | I would like to be able to have two to three levels of licensing for my projects: 36 | 37 | * **Free for Non-Commercial Usage** - basically if you are using my code as a student, hobbyist, or for an initial prototype: just use it. No warranty or expectations of support should exist. 38 | * **Licensed, no warranty** - If someone is a passive user of my code for a commercial project, but does not need customization or support, I'd like them to pay a smaller, one time fee in order to support my work. 39 | * **Licensed, with warranty** - If someone makes heavy usage of my work for a commercial project, and expects customization, support, security updates and response, etc., I'd like them to pay a recurring fee in order to support my work. 40 | 41 | In the **Free for Non-Commercial Usage** case, the software would be released under a specifically non-commercial license, such as one of the [Creative Commons Non-Commercial](https://creativecommons.org/licenses/by-nc-sa/4.0/) licenses, or the [Prosperity Public License](https://prosperitylicense.com/). The source would be widely available (likely published on GitHub and package managers like crates.io), but with no expectations of support or warranty. 42 | 43 | In the **Licensed, no warranty** case, the expectations would be similar to the **Free for Non-Commercial Usage** case, however the user would be granted a limited, non-transferrable, proprietary license for the software in question based on a one-time purchase. Ideally: This would be achieveable with little human interaction, such as a web store (incl. Stripe, Github Sponsors, Patreon) with a flat purchasing rate. 44 | 45 | In the **Licensed, with warranty** case, the user could be expected to make feature requests, receive support, and have timely security updates. The user would be expected to make a recurring yearly payment for this level. 46 | 47 | ## How do I think I would do this? 48 | 49 | I spend nearly all of my time working in Rust, so here is a "strawman" implementation of how I think this could work in that environment. This post assumes you are familiar with Rust, Cargo, and the Crates.io package registry. 50 | 51 | In particular, any DRM scheme I can imagine would be easily defeated by determined individuals, so this approach aims to be as unobstructive as possible to both commercial and non-commercial usages. 52 | 53 | ### Summary of process 54 | 55 | 1. When authoring a library or application, the author lists the package under a non-commerical license, such as the Prosperity License. 56 | 2. The Author also includes a unique-to-the-project asymmetric public key (e.g. ed25519) used to sign licenses of the project 57 | 3. The author includes a `build.rs` script that validates the license selected by the user. This would be invoked at compile time. 58 | 4. When depending on the library in question, the user would be expected to provide a metadata file in their project, such as `license-$libraryname.toml`. This file would contain one of the following kinds of content: 59 | 1. A line stating that the project is for non-commercial usage, e.g. "no license" 60 | 2. Contents that include the contact email, project name, a randomly generated license ID (and/or one-time pad), as well as a signature created from the library's private key of the above data 61 | 3. Contents that include the contact email, project name, license ID (and/or one-time pad), AND an expiration date, as well as a signature created from the library's private key of the above data 62 | 5. If the user failed to provide the above metadata, the `build.rs` script would cause the build to fail. 63 | 64 | An example of a non-commercial license file: 65 | 66 | ```toml 67 | # license-example-lib.toml 68 | 69 | usage = "non-commercial" 70 | ``` 71 | 72 | An example of a commercial license file: 73 | 74 | ```toml 75 | # license-example-lib.toml 76 | 77 | contact-email = "user@example.com" 78 | project = "good-example" 79 | usage = "licensed" 80 | 81 | # uuid 82 | license-id = "5a001d53-b6ab-4f64-996a-f710dcdbc637" 83 | 84 | # 64-byte ed25519 signature of the above metadata, as hex 85 | license-signature = "feedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafe" 86 | ``` 87 | 88 | An example of a warrantied license file: 89 | 90 | ```toml 91 | # license-example-lib.toml 92 | 93 | contact-email = "user@example.com" 94 | project = "good-example" 95 | usage = "warrantied" 96 | 97 | # uuid 98 | license-id = "5a001d53-b6ab-4f64-996a-f710dcdbc637" 99 | 100 | # datetime, as rfc3339/iso8601 format 101 | expiration = "2022-04-20T23:20:50.52Z" 102 | 103 | # 64-byte ed25519 signature of the above metadata, as hex 104 | license-signature = "feedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafefeedcafe" 105 | ``` 106 | 107 | ### Technical notes 108 | 109 | In this approach, the license key would be tied to a specific project and contact person (could also be a blanket `license@example.com` address). 110 | 111 | By checking the signature at build time, the `build.rs` script would not require internet access at the time of build, only the library public key (contained in the library itself), and the signature (contained in the project directory, which is accessible from a `build.rs` script). 112 | 113 | This means that internet access is only required when purchasing a license, which is either a one-time task (for the second tier of support), or a once-per-year task (for the third tier of support). 114 | 115 | It is *absolutely* possible to subvert this approach trivially, including: 116 | 117 | * Disabling the `build.rs` script 118 | * Changing the public key in the crate metadata 119 | 120 | If someone wants to get around the restrictions of the license, I likely cannot stop them, at least not indefinitely. This is intended to be a speed bump for well-meaning and law-abiding commercial users. 121 | 122 | ### Financial notes 123 | 124 | Unfortunately, "receiving money from people potentially in other countries" is often the most challenging part of the equation, especially for individuals not set up as a freelancer or as part of a company. 125 | 126 | The technical side of issuing a license is likely relatively trivial: consisting of a bot that generates and signs tokens after a transaction. 127 | 128 | For indivuals interested in this license approach but NOT set up to receive funds, they could instead request a donation to a charity of their choice, or to a fellow OSS maintainer that is. Automation of this is likely more difficult, but could probably be implemented in a lo-fi "send me a screenshot of your donation" method, and manually issuing licenses using a CLI script. 129 | 130 | ## Where to go from here? 131 | 132 | I dunno. This was on my brain, and I had to write it out to get it off of my head. 133 | 134 | If there is a positive response to this, I'll likely write a proof of concept implementation. 135 | 136 | I'd be interested in your feedback in the form of PRs or Issues on this repo, as well as sharing it with people you think might be interested. 137 | 138 | Feel free to [send me an email](james@onevariable.com) if you'd like to chat privately about it. 139 | --------------------------------------------------------------------------------