Select programming language for code examples

linkAuto-updates

Below you will find resources on how to implement auto-updates into your product, depending on the framework you're using, e.g. Electron, Sparkle, NSIS, etc.

Typically, a custom auto-update system would utilize the release upgrade endpoint to check for an upgrade, and then download and apply the upgrade when available.

We are working on official compatibility packages for popular open-source auto-update frameworks and package managers. Please let us know what frameworks you'd like to see supported. Have questions about how to integrate with a particluar framework or package manager? Reach out — we'd love to help.

linkAuto-updates for Go programs

You can integrate our Go SDK to implement license activation and automatic upgrades into your Go program. Installing an upgrade will replace the currently running binary with the new binary. After a restart, the end-user will be on the upgraded version.

Please do not embed admin, environment or product API tokens within client-facing code. Instead, your Go application should use the license's key or an API token — either a user token or a license token that belongs to a license. This will ensure that the licensee has permission to access the given release.

Configuration

Variable Required Description
keygen.Account Yes Your Keygen account ID. You can find your account ID here.
keygen.Product Yes Your Keygen product ID. You can find your product here.
keygen.LicenseKey No A license key used for API authentication. This will be used for license validations, activations, and for licensed upgrades.
keygen.Token No A license token used for API authentication. This will be used for license validations, activations, and for licensed upgrades.

Whether to use LicenseKey or Token depends on the license policy's authentication strategy. Setting it to LICENSE will require a license key, TOKEN a license token, and MIXED will allow either. LicenseKey will take precedence over Token if both are provided.

If your product uses an OPEN distribution strategy, a LicenseKey or Token is not required.

Example main.go

import "github.com/keygen-sh/keygen-go"
 
func upgrade() error {
keygen.Account = "1fddcec8-8dd3-4d8d-9b16-215cac0f9b52"
keygen.Product = "1f086ec9-a943-46ea-9da4-e62c2180c2f4"
keygen.LicenseKey = "C1B6DE-39A6E3-DE1529-8559A0-4AF593-V3"
 
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 nil
case err != nil:
fmt.Println("Upgrade check failed!")
 
return err
}
 
// Install the upgrade
if err := release.Install(); err != nil {
panic("Upgrade install failed!")
}
 
fmt.Printf("Upgrade complete! Installed v%s. Please restart.\n", release.Version)
}

linkAuto-updates for Tauri apps

You can use the official Tauri engine to implement dead-simple automatic upgrades for your Tauri applications.

Example tauri.conf.json

{
"tauri": {
"updater": {
"active": true,
"endpoints": [
"https://api.keygen.sh/v1/accounts/demo/engines/tauri/app?platform={{target}}&arch={{arch}}&version={{current_version}}"
],
"dialog": false,
"pubkey": "..."
}
}
}

linkAuto-updates for Electron apps

Electron Builder

You can use the official Keygen provider for electron-builder to implement auto-updates for your Electron app. In addition, you can configure electron-builder to automatically publish new releases and artifacts to our API.

Please do not embed admin, environment or product API tokens within client-facing code. Instead, your Electron application should use the licensee's API token — either a user token or a license token that belongs to a license.

A full example app is available on our GitHub. We also have a how-to blog post.

Configuration

A Keygen product token is required for publishing. You can generate a product token from your dashboard. After generating a product token, define a KEYGEN_TOKEN environment variable and set its value to the product token. Outside of your local environment and CI/CD environments, your product token should never be shared.

In addition to the above, the following config must be defined in your package.json:

Key Description
build.publish.provider The publisher/provider to use. This value must be set to keygen.
build.publish.account Your Keygen account ID. You can find your account ID here.
build.publish.product Your Keygen product ID. You can find your product ID here.
build.publish.channel The channel used for publishing and updates. Available options are here.

Example electron-builder config

# Set the required KEYGEN_TOKEN environment variable be able to publish
# releases using electron-builder's official Keygen publisher
export KEYGEN_TOKEN="{PRODUCT_TOKEN}"
// Configure electron-builder in your package.json
{
"main": "main.js",
"scripts": { ...
"postinstall": "electron-builder install-app-deps",
"start": "electron .",
"dist": "electron-builder build --publish always"
},
"build": {
"publish": {
"provider": "keygen",
"account": "<account>",
"product": "<product>",
"channel": "stable"
}
},
"dependencies": { ...
"electron-updater": "^4.5.0"
},
"devDependencies": { ...
"electron": "^12.0.1",
"electron-builder": "^22.13.0"
}
}

Example electron-builder auto-updater

const { autoUpdater } = require('electron-updater')
 
// Pass in a license key to authenticate with the API
autoUpdater.addAuthHeader(`License ${key}`)
 
// Or... pass in an API token that belongs to the licensee (i.e. a user
// token or a license token)
// autoUpdater.addAuthHeader(`Bearer ${token}`)
 
// Check for updates
autoUpdater.checkForUpdatesAndNotify()

linkAuto-updates for Mac apps

You can integrate our distribution API with tools such as Sparkle and Squirrel to provide automatic updates.

For Sparkle, generating an appcast.xml should be handled by Sparkle's tooling, or be generated by hand outside of Keygen. You can use Keygen's CLI to upload your notarized release files, as well as your appcast file.

For Squirrel, we recommend using their static JSON mode and uploading an artifact containing a valid JSON payload pointing to the latest release, according to Squirrel's schema.

In the future, we'll be adding official API endpoints for popular tooling such as Sparkle, to automate XML Appcast generation. Please reach out to [email protected] if you'd like to be a part of our beta process for that!

Please do not embed admin, environment or product API tokens within client-facing code. Instead, your Mac application should use the licensee's API token — either a user token or a license token that belongs to a license. This will ensure that the licensee has permission to access the given release.

Sparkle

Included is an example appcast.xml file, as well as an example written in Swift of authenticating with our API before calling Sparkle to check for an update.

Your Sparkle feedURL should look like this and should contain your appcast.xml file:

https://api.keygen.sh/v1/accounts/&lt;account&gt;/artifacts/appcast.xml

Please don't hesitate to reach out if you need help integrating with Sparkle or Squirrel.

Example appcast.xml

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Releases for Example</title>
<description>Most recent changes with links to upgrades.</description>
<language>en</language>
<item>
<title>Cool App 2.0</title>
<link>https://cool-app.example</link>
<sparkle:version>
2.0.0
</sparkle:version>
<description>
<![CDATA[Cool app's 2.0 changelog here.]]>
</description>
<pubDate>Mon, 25 Oct 2021 14:05:04 GMT</pubDate>
<enclosure
url="https://api.keygen.sh/v1/accounts/<account>/artifacts/Cool%20App%202.0.zip"
sparkle:edSignature="WVyVJpOx+a5+vNWJVY79TRjFKveNk+VhGJf2iti4CZtJsJewIUGvh/1AKKEAFbH1qUwx+vro1ECuzOsMmumoBA=="
length="1623481"
type="application/octet-stream" />
</item>
</channel>
</rss>

Example AppDelegate.swift

import Sparkle
 
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
lazy var updater = SPUUpdater(
hostBundle: Bundle.main,
applicationBundle: Bundle.main,
userDriver: SPUStandardUserDriver(hostBundle: Bundle.main, delegate: nil),
delegate: self
)
 
@IBAction func checkForUpdates(_: Any) {
updater.httpHeaders = [
// Prompt for and pass in an API token that belongs to the licensee (i.e. a
// user or license token). This is optional for product's with an "OPEN"
// distribution strategy, since authentication is not required.
"authorization": "Bearer \(getToken())"
]
 
updater.checkForUpdates()
}
}