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)
- Open Products, select the product, ensure RSA keys exist.
- Create or pick a software release (required on create in the API).
- Open Licenses → create license; set
Typeto Perpetual (case-insensitive enum string). - Fill Name, IssuedTo (customer / org), optional ExpirationDate (e.g. maintenance window), Issuer, Notes.
- Optional: attach entitlement sets so features appear in the signed payload.
- After save, use Download / generate file actions in the dashboard to obtain
license.binfor 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 usesCreateLicenseDto:type: "Perpetual",name,issuedTo,softwareReleaseId(required), optional dates andentitlementSetIds.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/validate—multipart/form-data:licenseKey,validationParams(JSON string), optionallicenseFile.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 (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.
