Open, source-available — the new KeygenStar us on GitHub arrow_right_alt

Announcing: Multi-User Licenses

Monday, April 29th 2024

When Keygen first launched almost 8 years ago, we set up a way to associate a user to a license via the license's singular user relationship. In the beginning, we thought that this would be enough. But over time, this singular user relationship showed many problems, namely that there was no way to model multi-user licenses in Keygen.

To work around this, many customers would use machines to attach "users" to licenses, where the "machine's" fingerprint was populated with the user's email address. This would allow licenses to be "multi-user", in a sense. But then how can we also track which machines each "user" has activated, or how many processes each "user" has?

Simply put — we can't, because machines were being retrofitted to model users.

Another, arguably worse, workaround was to issue 𝑛 licenses, one for each user. This approach would work when 𝑛 was small, but when 𝑛 was hundreds or thousands of users, the time it would take to generate licenses in bulk was unacceptable.

What do I mean by that? Imagine you got an order for a license for 1,000 users. You would need to make over 2,000 API requests to fulfill that order: a request to create each user, and a request to create a license for each user. In addition to the latency problem, being rate limited was also a risk. This made the previous approach of using machines more preferable, even if it wasn't what the API was designed for.

In addition, with the multi-license approach, the licenses and users end up being fragmented, and you would also need to separately manage them when it came to expirations and renewals. You could add licenses and users to groups to keep things organized, but there were still significant latency and operational costs.

Both approaches were messy, but they worked (more or less). But today I'm super excited to announce that starting now, we have full support for multi-user licenses in Keygen!

Alongside the existing singular user relationship for licenses (which has been renamed to owner), there is now a plural relationship called users. Users can be attached to any number of licenses and gain permission to perform other actions on the license, such as validation, and machine activation and deactivation.

In addition, users can be attached and detached in bulk, meaning those that are selling licenses with potentionally thousands of seats now have a solution that will not require 𝑛⋅2 API requests to issue 𝑛 user licenses. Instead, simply create a license, and attach 𝑛 users (up to 100 at a time). So we go from thousands of API requests, to tens. (And this is even more efficient when users are created on-demand.)

This means there are now 2 types of license <> user relationships:

  1. The license owner. This is the singular relationship we've always had, just renamed, and nothing is changing permission-wise by default. It remains optional.
  2. The license user. This is the new plural relationship.

License users do have a more limited set of permissions than a license owner (formerly the license user), so they're a great fit for use-cases where you don't want to allow the full suite of available actions on a license for a user.

For example, machine's also have a new owner relationship, and this must be provided when a license user activates a machine for a license they're attached to. In addition, license users can only deactivate machines of which they're the owner.

This is in contrast to the behavior for license owners, where they can activate and deactivate any machine for their license.

Note on backwards compatibility: there are no breaking changes to worry about. Thanks to version pinning, you do not have to make any changes to your Keygen integration. You can opt-in if this is something you're interested in, but no pressure.

If you'd like to opt-in, you can use the Keygen-Version: 1.6 header and start attaching users to licenses today by using the attach user method on the license's users relationship.

Right now, this is an API-only feature. We'll be adding multi-user functionality to the Dashboard soon.

The full changeset can be found in our changelog.

Until next time.

p.s. We'll be sharing more technical details about how were able to make this change soon, as well as releasing a few Rubygems that we built to make this migration easier. A lot went into this seemingly simple change — over 19k lines of code were written across a near 6 month timespan.