Keygen CLI

Before getting started, you'll need to sign up for an account with Keygen. You will also want to go ahead and create your first product, and an API token for the product. We'll use both of these when publishing releases for our product.

Introduction

Keygen's CLI helps you sign and distribute software releases. It can be used to securely publish software applications from the command line, or from CI/CD environments. Keygen's CLI itself is published using the CLI, and it utilizes our Go SDK for automatic upgrades, which is all backed by Keygen's distribution API (it's dogfooding all the way down!)

Fun fact: the keygen CLI does not require a license — it uses an OPEN distribution strategy, which allows us to distribute releases without a license.

The source code for the CLI is available here.

Installation

The keygen CLI is packaged as a single executable for Linux, macOS, Windows, and other platforms. The precompiled binaries have no external dependencies and there is no installation program — all you need to do is download and move the binary to a location of your choice for easy system-wide use, e.g. /usr/local/bin, /usr/bin, or some other location in your $PATH.

To quickly install the keygen CLI, you can run the following script:

curl -sSL https://raw.pkg.keygen.sh/keygen/cli/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 keygen into /usr/local/bin.

Manual installation

To install manually, download the appropriate keygen 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 ./keygen_darwin_arm64
mv ./keygen_darwin_arm64 /usr/local/bin/keygen

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

keygen --help

Commands

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

CLI to interact with keygen.sh
 
Usage:
keygen [command]
 
Available Commands:
del delete an existing release
genkey generate an ed25519 key pair for code signing
help help for a command
new create a new draft release
publish publish an existing release
tag tag an existing release
untag untag an existing release
upload upload a new artifact for a release
version print the current CLI version
yank yank an existing release
 
Flags:
-h, --help help for keygen
--no-color disable colors in command output [$NO_COLOR=1]
-v, --version version for keygen
 
Use "keygen [command] --help" for more information about a command.

Generate a key pair

Generate an Ed25519 public/private key pair, 2 files in the current directory, the public key keygen.pub and the private key keygen.key. The public key can be safely embedded within your app to cryptographically verify that upgrades are signed by yourself (or your team).

Since only you possess the private key, this will cryptographically prove that you (or your team) created and published a given release.

Never share your private key, keygen.key, with anyone. Always keep your private key in a secure location, never in source control.

keygen genkey

For more usage options run keygen genkey --help.

Create a release

Create a new release. This command will create a new release object. The release's status will be in a DRAFT state, unlisted until published. Think of a release as a versioned bucket of artifacts.

keygen new \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--channel 'stable' \
--version '1.0.0'

For more usage options run keygen new --help.

Upload an artifact

Upload an artifact at <path> to a given release. A SHA-512 checksum will automatically be generated for the release. In addition, When the --signing-key flag is provided, the release will be signed using Ed25519ph (with the option to sign using Ed25519 instead, for compatibility with tools like Sparkle). Releases can have many artifacts.

keygen upload ./build/keygen_linux_arm64 \
--signing-key ~/.keys/keygen.key \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release '1.0.0' \
--platform 'linux' \
--arch 'arm64'

For more usage options run keygen upload --help.

Publish a release

Publish an existing release. This command will set the release's status to PUBLISHED.

keygen publish \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release '1.0.0'

For more usage options run keygen publish --help.

Tag a release

Tag an existing release. This command will set the release's tag to the provided value. For example, tag a latest release.

keygen tag 'latest' \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release '1.0.0'

For more usage options run keygen tag --help.

Untag a release

Untag an existing release. This command will set the release's tag to nil. For example, untag a latest release before tagging a newer release.

keygen untag \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release 'latest'

For more usage options run keygen untag --help.

Yank a release

Yank an existing release. Sometimes things go wrong, and this command will set the release's status to YANKED, unlisting it.

keygen yank \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release '1.0.0'

For more usage options run keygen yank --help.

Delete a release

Delete an existing release. Sometimes things go really wrong, and this command will delete the release and all of its artifacts.

keygen del \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release '1.0.0'

For more usage options run keygen del --help.

Delete an artifact

Delete an existing artifact. Sometimes an upload may fail, or the wrong file is uploaded, and this command will delete the artifact.

keygen del \
--account '1fddcec8-8dd3-4d8d-9b16-215cac0f9b52' \
--product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \
--token 'prod-xxx' \
--release '1.0.0' \
--artifact 'keygen_linux_arm64'

For more usage options run keygen del --help.

Upgrading

To check for an upgrade to the CLI, run the following command and follow the prompts to install. Unless KEYGEN_NO_AUTO_UPGRADE is set, or the --no-auto-upgrade flag is passed, the CLI will automatically check for upgrades no more than once a day.

keygen upgrade

For more usage options run keygen upgrade --help.


Environment variables

Some flags can be set using environment variables so that they do not need to be specified, saving them from being logged to your shell's history. This is also useful in CI/CD environments.

export KEYGEN_ACCOUNT_ID='1fddcec8-8dd3-4d8d-9b16-215cac0f9b52'
export KEYGEN_PRODUCT_ID='2313b7e7-1ea6-4a01-901e-2931de6bb1e2'
export KEYGEN_PRODUCT_TOKEN='prod-xxx'
export KEYGEN_SIGNING_KEY_PATH='~/.keys/keygen.key'
export KEYGEN_SIGNING_KEY='xxx'
export KEYGEN_NO_AUTO_UPGRADE=1

Code signing

Signing your releases provides end-to-end guarantees that releases are solely created by you, the software vendor, and no one else. You could distribute your releases via trusted third-parties, such as Keygen, or even an untrusted third-party, and still maintain the guarantee that the binary you built and published is the binary that the end-user is using. This is proven, cryptographically.

As an example, using our Go SDK, you would set the PublicKey parameter of keygen.Upgrade() to the value of your hex-encoded Ed25519 public key (this will be the text inside of the keygen.pub file).

This Ed25519 public key is different than your Keygen account's Ed25519 public key. This is a personal public key, where only you possess the private key. This ensures that nobody, not even us, possess the private key which proves a release was created by you.

Your Keygen account's public key is used for verifying the signature of API responses. We keep the private key safe, so that you can prove a given response was actually created by Keygen. We keep the private key secure.

In a similar way, your personal public key is used for verifying release signatures. Our Go SDK uses this public key to prove that a given release was actually created by you. You keep the private key secure.

opts := keygen.UpgradeOptions{
PublicKey: "5ec69b78d4b5d4b624699cef5faf3347dc4b06bb807ed4a2c6740129f1db7159",
CurrentVersion: "1.0.0",
Channel: "stable",
}
 
// Check for an upgrade
release, err := keygen.Upgrade(opts)
 
// ...

Using your newly generated public key, the SDK will automatically verify the release's signature during the upgrade process, in addition to the SHA-512 checksum, before installing an upgrade. If the signature or checksum fails verification, the upgrade will be aborted with an error.

Always keep your private key in a secure location. If your private key is ever compromised, please generate a new key pair.


Automatic upgrades

You can integrate our Go SDK to add auto-update functionality to a Go application. Installing an upgrade will replace the currently running binary with the latest version for the current platform. Check out the following code snippet to add auto-updates to your Go app.

opts := keygen.UpgradeOptions{CurrentVersion: "1.0.0", Channel: "stable", PublicKey: "5ec69b78d4b5d4b624699cef5faf3347dc4b06bb807ed4a2c6740129f1db7159"}
 
// Check for an upgrade
release, err := keygen.Upgrade(opts)
switch {
case err == keygen.ErrUpgradeNotAvailable:
fmt.Println("No upgrade available, already at the latest version!")
 
return
case err != nil:
fmt.Println("Upgrade check failed!")
 
return
}
 
// Install the upgrade
if err := release.Install(); err != nil {
panic("Upgrade install failed!")
}
 
fmt.Println("Upgrade complete! Please restart.")

If you wanted to, you could prompt the user for confirmation between calling keygen.Upgrade and release.Install (which is actually what our CLI does.)


Support

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