Keygen Relay Beta

Keygen Relay helps you securely distribute node-locked licenses in offline and air-gapped customer environments, backed by Keygen Cloud or a self-hosted instance of Keygen.

Relay, in it's simplest form, is a small server that sits on a local network, which has a pool of licenses — a license file and license key pair — to distribute to nodes on a first-come, first-served basis. Relay provides a vendor-facing CLI for management, as well as an app-facing server and API for claiming and releasing these licenses on behalf of the nodes.

Relay is built on top of Keygen's concept of license files, which are a cryptographically signed and encrypted snapshot of a license object. As such, they are tamper-proof, and a powerful building block for any offline licensing solution.

Relay is not a drop-in replacement for Keygen Cloud or a self-hosted instance of Keygen. It is built on top of Keygen, offering a small API for claiming and releasing licenses on behalf of nodes in a local network.

The source code for Relay is available here.

Background

Relay was developed to solve a problem in cloud-based licensing APIs: implementing node-based licensing models, such as floating licenses, in air-gapped or offline environments. These environments pose challenges since external licensing APIs require an internet connection, preventing nodes from communicating with the API, making it difficult to track activations or assert node limits in an automated way.

Workarounds involved using intermediaries, like mobile devices, to activate licenses and checkout machine files for offline nodes from a web portal, but this method is fragile and relies on human intervention, which is impractical in the age of automated cloud environments.

This limitation is especially evident in scenarios requiring automated licensing of highly volatile nodes, e.g. autoscaling clusters of hundreds or even thousands of nodes.

Relay was created to be an easy-to-deploy bridge between Keygen and the offline universe, secured via cryptography.

Installation

Relay is packaged as a single standalone executable for Linux, macOS, Windows, and other platforms. The prebuilt binaries have no external dependencies and there is no installation program — all you need to do is download and move the binary to an accessible path.

To quickly install relay, you can run the following script:

curl -sSL https://raw.pkg.keygen.sh/keygen/relay/latest/install.sh | sh
Want to see that script before running it? It's open source on GitHub.

The script will auto-detect your platform and install relay into /usr/local/bin.

Manual installation

To install manually, download the appropriate relay binary for your platform:

Once downloaded, give the binary executable permissions and move it to /usr/local/bin, or some other directory that's in your $PATH.

chmod +x ./relay_linux_arm64
mv ./relay_linux_arm64 /usr/local/bin/relay

Finally, confirm it's installed by running the following:

relay --help

Commands

For all available commands and options, run relay --help.

relay is a small command line utility that distributes license files to nodes on a local network
 
Usage:
relay [command]
 
Available Commands:
add push a license to the local relay server's pool
completion Generate the autocompletion script for the specified shell
del delete a license from the local relay server's pool
help Help about any command
ls print the local relay server's license pool, with stats for each license
serve run the relay server to manage license distribution
stat print stats for a license in the local relay server's pool
version print the current relay version
 
Flags:
--database string specify an alternate database path (default "./relay.sqlite")
-h, --help help for relay
--no-audit disable audit logs
--no-color disable colors in command output [$NO_COLOR=1]
-v, --verbose count log verbosity e.g. -vvv (default "error")
--version version for relay
 
Use "relay [command] --help" for more information about a command.

CLI

The CLI can be used by the vendor to setup and manage customer environments before starting the Relay server. The CLI is primarily used to add and manage licenses — a license file and license key pair — to the pool of available licenses. Relay will then distribute those licenses to nodes on a first-come, first-served basis.

Add license

You can add a new license to the pool using the add command. You can use this command to bootstrap a customer environment with a pool of license files, which your application will consume from Relay, cryptographically verifying and decrypting them just as you would normally under Keygen Cloud or a self-hosted Keygen instance.

relay add --file ./license.lic --key 9A96B8-FD08CD-8C433B-7657C8-8A8655-V3 \
--public-key e8601e48b69383ba520245fd07971e983d06d22c4257cfd82304601479cee788

The add command supports the following flags:

Flag Description
--file Path to the license file to add to the pool.
--key License key for decryption.
--public-key Your Ed25519 public key for license verification.

You can find your Ed25519 public key here.

Delete license

To delete a license, use the del command. You can use this command to remove license files from the pool that are no longer needed.

relay del --license dcea31a4-1664-4633-9f52-4a1b0b5ea2ef

The del command supports the following flags:

Flag Description
--license The unique ID of the license to delete from the pool.

List licenses

To list all the licenses in the pool, use the ls command. You can use this command to audit the licenses in the pool, e.g. view which licenses are claimed by a node, and other information such as total claims per-license.

relay ls

The ls command supports the following flags:

Flag Description
--plain Print results non-interactively in plaintext.

Stat license

To retrieve the status of a specific license, use the stat command. You can use this command to get information on a particular license, e.g. to see which node has a claim on it, or to see how many total claims it has had over its lifetime.

relay stat --license dcea31a4-1664-4633-9f52-4a1b0b5ea2ef

The stat command supports the following flags:

Flag Description
--license The unique ID of the license to retrieve info about.
--plain Print results non-interactively in plaintext.

Server

The server is the heart of Relay. This is the entrypoint that your application will interact with to consume, i.e. claim and release, licenses on behalf of nodes.

To start the relay server, use the following command:

relay serve --port 6349

The serve command supports the following flags:

Flag Description Default
--port, -p Specifies the port on which the relay server will run. 6349
--no-heartbeats Disables the heartbeat mechanism. When this flag is enabled, the server will not automatically release inactive or dead nodes. false
--strategy Specifies the license assignment strategy. Options: fifo, lifo, rand. fifo
--ttl, -t Sets the time-to-live for license claims. Licenses will be automatically released after the time-to-live if a node heartbeat is not maintained. Options: e.g. 30s, 1m, 1h, etc. 30s
--cleanup-interval Specifies how often the server should check for and clean up inactive or dead nodes. 15s
--database Specify a custom database file for storing the license and node data. ./relay.sqlite

E.g. to start the server on port 8080, with a 30 second node TTL and FIFO distribution strategy:

relay serve --port 8080 --ttl 30s --strategy fifo

Your application would then consume licenses on port 8080 of the local network.

API

The API, served by Relay, can be consumed by the vendor's application to claim and release a license on behalf of a node.

Claim license

Nodes can claim a license by sending a PUT request to the /v1/nodes/{fingerprint} endpoint:

curl -v -X PUT "http://localhost:6349/v1/nodes/$(cat /etc/machine-id)"

Accepts a fingerprint, an arbitrary string identifying the node. This can be anything — a hardware ID, a UUID, the OS GUID, etc. In the end, what is used to identify a node is up to you.

Returns 201 Created with a license_file and license_key for new nodes.

If a claim already exists for the node, the claim is extended by --ttl and the server will return 202 Accepted, unless heartbeats are disabled and in that case a 409 Conflict will be returned. If no licenses are available to be claimed, i.e. no licenses exist or all have been claimed, the server will return 410 Gone.
{
"license_file": "LS0tLS1CRUdJTiBMSUNFTlNFIEZJTEUtLS0tL...S0NCg0K",
"license_key": "9A96B8-FD08CD-8C433B-7657C8-8A8655-V3"
}

The license_file will be base64 encoded.

Release license

Nodes can release a license by sending a DELETE request to the /v1/nodes/{fingerprint} endpoint:

curl -v -X DELETE "http://localhost:6349/v1/nodes/$(cat /etc/machine-id)"

Accepts a fingerprint, the node fingerprint used for the claim. This must match the fingerprint that was used for the claim exactly.

Returns 204 No Content with no content.

If a claim does not exist for the node, the server will return a 404 Not Found.

Logs

Relay comes equipped with audit logs out-of-the-box, allowing the full history of the Relay server to be audited. For example, to see when a license was released by Node A and claimed by Node B, or when a claim on a license was automatically released.

Audit logs can be viewed using a SQLite client, providing the path to the Relay database:

sqlite3 ./relay.sqlite
> select * from audit_logs order by created_at desc limit 25;

If you have concerns about storage, please use Relay's --no-audit flag.


Support

Questions? We'd be happy to help! Reach out at [email protected].