LicenPro
DocumentationPerpetual license

Perpetual license

A perpetual license grants ongoing rights to use the software under the entitlements you attach. The signed license.bin can be validated offline (RSA signature + local checks) while optional online validation enables sessions, revocation awareness, and usage tied to the dashboard.

RSA signed

Tampering with the file breaks the signature.

Online or offline

SDK defaults to online validation; offline path available.

Issued to

Customer or org identifier stored on the license.

How it works

When you create a perpetual license, the server stores a License row, assigns a license key, and can generate a binary license file signed with the product’s RSA private key (never leaves LicenPro). The SDK loads license.bin, verifies the signature with your embedded public key, and checks that the license key in options matches the payload.

The payload model includes RequiresOnlineValidation on PerpetualLicense: when the issued file marks the license as requiring online checks, the SDK’s online flows enforce that policy (see LicenseManager perpetual handling). Most perpetual files are issued for offline-friendly use; your product settings and issuance pipeline determine the flag.

Creating a perpetual license (dashboard)

  1. Open Products, select the product, ensure RSA keys exist.
  2. Create or pick a software release (required on create in the API).
  3. Open Licenses → create license; set Type to Perpetual (case-insensitive enum string).
  4. Fill Name, IssuedTo (customer / org), optional ExpirationDate (e.g. maintenance window), Issuer, Notes.
  5. Optional: attach entitlement sets so features appear in the signed payload.
  6. After save, use Download / generate file actions in the dashboard to obtain license.bin for the customer.

REST API (vendor-authenticated)

These routes live under your API base (e.g. https://your-host/api). License list/create/update require a logged-in user JWT unless you build a separate integration.

  • POST /api/Licenses — body uses CreateLicenseDto: type: "Perpetual", name, issuedTo, softwareReleaseId (required), optional dates and entitlementSetIds.
  • GET /api/Licenses/{id}/download — download signed license file bytes.
  • POST /api/Licenses/{id}/generate-file — (re)generate file payload when permitted.

REST API (anonymous + product API key)

Server-side validation without the bin file uses the product API key header X-API-KEY (see ApiKeyAuthFilter):

  • POST /api/Licenses/validatemultipart/form-data: licenseKey, validationParams (JSON string), optional licenseFile.
  • GET /api/Licenses/validate/{licenseKey}?hardwareId=... — lightweight check.
  • GET /api/Licenses/status/{licenseKey}?hardwareId=... — status payload for SDK-style clients.

SDK integration

Use LicenseClient with ExpectedLicenseType = LicenseType.Perpetual when you want a hard type guard.

using LicenPro.SDK;
using LicenPro.SDK.Enums;

await using var client = new LicenseClient(new LicenseClientOptions {
    LicenseFilePath = "C:/ProgramData/MyApp/license.bin",
    PublicKey = publicKeyBase64NoPemHeaders,
    LicenseKey = "LP-....",
    ExpectedLicenseType = LicenseType.Perpetual
});

var result = await client.ValidateAsync();

if (result.IsValid)
{
    // result.License — inspect type / features
}
else
{
    // result.Status: Expired, Revoked, SignatureMismatch, ...
}

Offline-only validation after you already trust the file: await client.ValidateOfflineAsync() (no live server round-trip for the load path defined in the SDK).

Online vs offline (summary)

Online (ValidateAsync): signature + credential checks, server revocation / device block, activation, optional session heartbeat. Offline (ValidateOfflineAsync): cryptographic and local checks only — suitable air-gapped or fallback when policy allows.

See also