■ ZERO_TOKEN // BETA
[ DOCS ] [ LOGIN → ]

Developer Guide: Integrating Desktop Application Licensing

This guide explains how to use the Zero Token License Server to create, distribute, and validate licenses for a desktop application. The system relies on a secure offline validation model using asymmetric ECDSA (P-256) keys, eliminating the need for constant network connectivity after initial activation.

1. Setup in the Dashboard

Before distributing your application, you must define the product and generate activation codes for your users.

Registering a Product

  1. Log in to the License Server Dashboard (license-server-dash).
  2. Navigate to the Products section and create a new Product.
  3. This creates a unique productId for your desktop application.

Generating Activation Codes

  1. Navigate to the Activation Codes section.
  2. Generate an activation code linked to your newly created Product.
  3. Distribute this Activation Code to your end-user (e.g., via email after a purchase). Note: Activation codes currently enforce a quantity and max machine limit of 1 per code.

2. Desktop Client Integration: Machine Binding

When the user launches your desktop application for the first time, it should prompt them for their Activation Code. The application must then bind the machine to this code to generate a license.

Capturing the Machine Fingerprint

Your application needs to collect hardware identifiers to create a unique machine fingerprint. The system uses the MachineFingerprintV2 format, which requires:

Calling the Bind API

Make an API request to the License Server to bind the machine and receive the license manifest.

Endpoint: POST /api/v3/licenses/bind

Payload:

{
  "activationCode": "YOUR-ACTIVATION-CODE-HERE",
  "machineFingerprint": {
    "macAddresses": ["00:1B:44:11:3A:B7"],
    "hostname": "user-pc",
    "os": "windows"
  }
}

The Server Response

Behind the scenes, the server:

  1. Validates the activation code.
  2. Extracts the productId.
  3. Delegates payload generation to the dll-generator-worker (which generates .dll, .so, or .dylib depending on the OS platform).
  4. Signs the license manifest with the Server’s Global ECDSA Private Key.

The response will contain the licenseFile—a base64-encoded representation of the license manifest (which also encapsulates the server’s ECDSA public key for offline verification).

Save this payload to disk (e.g., license.json or manifest.dll).

3. Desktop Client Integration: Offline Validation

Once the license is saved to the local machine, your application can perform offline verification on subsequent launches.

Fetching the Server Public Key (Optional/Initial)

For completely offline verification, the client can use the embedded public key within the license payload. However, clients can also fetch the global ECDSA public key explicitly:

Endpoint: GET /api/v3/license/public-key Requirement: The request strictly requires an Accept header containing either application/json or text/plain.

Verifying the License Locally

Your desktop SDK must:

  1. Load the licenseFile (the base64 payload from disk).
  2. Use the Web Crypto API (or equivalent native crypto library like OpenSSL/BoringSSL) to extract the manifest JSON and the signature.
  3. Verify the ECDSA (P-256, SHA-256) signature against the manifest using the provided public key.
  4. Verify that the productId in the manifest matches the expected product ID of your application.
  5. Generate the current machine fingerprint and verify it matches the fingerprint stored in the manifest (ignoring MAC addresses).

If the signature and fingerprint match, the application is fully licensed and can launch normally.

4. Periodic Online Validation (Optional)

If you require periodic check-ins or want to update the license state (e.g., for subscription renewals), your desktop client can re-validate with the server.

Endpoint: POST /api/v3/licenses/validate

Headers:

Payload:

{
  "machineFingerprint": {
    "macAddresses": ["00:1B:44:11:3A:B7"]
    // ... other fingerprint data
  }
}

The server will return an updated license object, including a potentially regenerated licenseFile base64 manifest that your application should map and save back to disk, replacing the old file.