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(theintegration.signingPublicKeyfield). - 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.
-
Productslug 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
| Area | Endpoint | Auth | Purpose |
|---|---|---|---|
| Runtime | POST /v1/activate | none | Activate a key on a machine → signed lease |
| Runtime | POST /v1/validate | none | Validate/refresh without consuming a seat |
| Admin | GET/POST /admin/products, /admin/products/{slug}/tiers | tenant token | Manage products & tiers |
| Admin | POST /admin/licenses, /admin/licenses/{id}/{revoke,renew,transfer,deactivate,offline-lease} | tenant token | Issue & manage licenses |
| Admin | GET /admin/licenses, /admin/overview, /admin/licenses/{id}/activations | tenant token | Reporting |
| Admin | GET/POST /admin/team | owner token | Team members |
| Platform | GET/POST /platform/tenants, /platform/plans, /platform/tenants/{id}/signing-key | platform token | Multi-tenant operator |
| Auth | POST /auth/login → /auth/mfa, /auth/session, /auth/sso | — | Dashboard sign-in → session token |
The full endpoint map is in the HTTP API reference.