Skip to content

Guide

Getting started

The end-to-end path for a vendor adding licensing to a .NET app: get a signing key, issue a license, verify it, and go live.

This is the end-to-end path for a vendor adding licensing to a .NET app: get a signing key, issue a license, verify it in your application, and go live. It assumes a running Keyright issuing service (the hosted service, or your own deployment) and the Keyright.NET SDK.

Throughout, $BASE is your issuing service URL (e.g. https://keyright.delta1labs.com), and $TOKEN is a tenant admin token — a team member’s session token for your workspace.

1. Get a signing key for your product

Every tenant signs licenses/leases with its own RSA key. The private key stays server-side (stored AES-256-GCM–encrypted under the service KEK); your app embeds only the public key.

  • New workspace: the service generates a key for your tenant. Fetch the public key from the dashboard’s Integration tab, or GET $BASE/admin/account (the integration.signingPublicKey field).
  • Bring your own key (e.g. to stay compatible with an existing product like Nebula.NET): import it with POST $BASE/platform/tenants/{id}/signing-key — pass the PKCS#8 private key. The derived public key is what your app embeds.

Copy the base64 public key; you’ll paste it into the SDK options in step 3.

2. Create a product, a tier, and a license

From the dashboard (Products → Add product, then open it and Add tier), or via the API:

# create the product
curl -X POST $BASE/admin/products -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
  -d '{"name":"Acme App","slug":"acme-app"}'

# add a tier (seat count + optional entitlements template)
curl -X POST $BASE/admin/products/acme-app/tiers -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
  -d '{"name":"pro","seats":3,"entitlements":{"export":"true","seats":"3"}}'

# issue a license (omit "id" to auto-generate a key; include it to import an existing one)
curl -X POST $BASE/admin/licenses -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
  -d '{"licensee":"Acme Inc.","product":"acme-app","tier":"pro","seats":3,"email":"owner@acme.com"}'
# -> { "id": "LIC-XXXXXXXX...", ... }   give this key to the customer

Quotas (active licenses, product count) are enforced per the tenant’s plan.

3. Verify the license in your app (SDK)

Install the SDK from NuGet:

dotnet add package Keyright.NET

Not on .NET? The same license format is verified by our other SDKs — npm (npm install keyright), PyPI (pip install keyright) and Maven Central (com.delta1labs:keyright).

Then configure it with your product slug, the embedded public key, and (for online activation) your service URL. See .NET SDK integration for the full API; the minimal shape:

var client = KeyrightClient.Initialize(new KeyrightOptions {
    Product = "acme-app",
    PublicKeyBase64 = "<your tenant public key>",
    ServiceUrl = "https://keyright.delta1labs.com", // base URL for online activation (optional)
});

// Online activation (recommended): binds this machine, returns a verified lease.
LicenseInfo info = await client.ActivateAsync(customerKey);

// Or, if you ship an offline license file / env var, just validate what's present:
LicenseInfo info2 = client.Validate();

if (info.IsPaid && client.IsEnabled("export")) { /* unlock the feature */ }

The SDK verifies the signature against your embedded public key, checks machine binding and expiry, caches the lease locally, and re-activates automatically before the lease expires. It fails closed to the free/unlicensed state if verification fails or the key is revoked.

4. Go-live checklist

  • Public key embedded in the shipping build matches the tenant’s current signing key.
  • Product slug in the SDK matches the product you issue licenses for (the server scopes activation by product).
  • Decide offline vs online (or both): offline file for air-gapped/enterprise, online activation for seat enforcement and revocation.
  • Seats and expiry set correctly on the tier/license; test hitting the seat limit.
  • Test the revocation path (POST /admin/licenses/{id}/revoke) — the app should drop to free on the next lease refresh.
  • Have a backup plan for the database and the KEK. Losing the KEK means losing every tenant’s signing key.
  • Have a signing-key rotation plan in place.
  • If selling via a store/Merchant-of-Record, wire fulfillment to POST /webhooks/fulfill/{slug} so paid orders auto-issue keys.

The API at a glance

AreaEndpointAuthPurpose
RuntimePOST /v1/activatenoneActivate a key on a machine → signed lease
RuntimePOST /v1/validatenoneValidate/refresh without consuming a seat
AdminGET/POST /admin/products, /admin/products/{slug}/tierstenant tokenManage products & tiers
AdminPOST /admin/licenses, /admin/licenses/{id}/{revoke,renew,transfer,deactivate,offline-lease}tenant tokenIssue & manage licenses
AdminGET /admin/licenses, /admin/overview, /admin/licenses/{id}/activationstenant tokenReporting
AdminGET/POST /admin/teamowner tokenTeam members
PlatformGET/POST /platform/tenants, /platform/plans, /platform/tenants/{id}/signing-keyplatform tokenMulti-tenant operator
AuthPOST /auth/login/auth/mfa, /auth/session, /auth/ssoDashboard sign-in → session token

The full endpoint map is in the HTTP API reference.