Browse the library
Documentation libraryGetting started
Core concepts
Clavis Authentication Engine is built from a short chain of nested objects: a workspace holds apps, an app issues licenses from plans, and a license is tied to devices, sessions and end users. Knowing how they fit together makes it easier to design what you sell and to follow every other guide.
9 min read
How the pieces relate
The table reads from the outside in. A workspace has many apps; an app has many license plans, licenses and variables; a license runs on at most the number of machines it allows; each machine can have a live session.
| Concept | Belongs to | ID shape | Managed in |
|---|---|---|---|
| Workspace | You and your teammates | Account & organization › Workspace & members | |
| App | One workspace | app_… | Workspace › Apps |
| Signing key | One app | kid, 16 hex characters | App security › Protection, tab Methods |
| Entitlement | One app | a key such as export_pdf | Licensing & releases › Sign-in & license plans |
| License plan | One app | pol_… | Licensing & releases › Sign-in & license plans |
| License | One app, made from one plan | lic_… | Licensing & releases › Licenses |
| Device | One license | dev_… | View details on a license |
| Session | One device on one license | ses_… | End users › Devices & sessions |
| End user | One app, linked to one license | usr_… | End users › Users |
| Variable | One app, by scope | Integration › Variables |
Workspace
The workspace is the top-level owner. Every new dashboard account gets a personal workspace on the Basic plan, with you as its owner. These belong to the workspace rather than to a single app:
- The service plan, Basic or Premium, and all its limits: how many apps, keys per day, machines per key, end-user accounts and days of log retention. See Account & organization › Plan & usage.
- Members in three roles: member (reads everything, manages licenses, end users and devices), admin (also apps, plans, variables, rules, webhooks, API keys) and owner (also deleting apps, billing and the team). See Workspaces, members and roles.
- Seller API keys and resellers, under the Business group.
App
Each product you ship is one app. Go to Workspace › Apps, click New app, enter a Name and click Create. The new app immediately gets an App ID shaped like app_…, its own signing key pair, and a default license plan called "Standard" (30 days, 1 machine).
Licenses, users, variables, webhooks, releases, access rules and logs all belong to one app and are never shared. Each app also picks a Sign-in mode under Licensing & releases › Sign-in & license plans: License key, Account, or Account + license key. Turning off Accept sign-ins in Integration › App settings makes every request from your software fail with app_paused.
Signing key and public key
Each app has an Ed25519 key pair. The secret half stays on the server, encrypted at rest, and signs every response, offline token and update manifest. The public half is shown on the app's Overview page (the first item in the block titled with your app's name) as Public key, next to the App ID.
You embed the public key in your software. It can only verify, never sign, so shipping it is safe, and the SDK rejects any answer not signed by a key the build trusts, which makes a fake server or a tampering proxy useless. Each key has a kid (the first 16 hex characters of its sha256). Rotation happens in the Signing keys panel of App security › Protection, tab Methods, in Advanced Protection; see Signing keys and rotation.
License and license key
A license is the right to use one app; the license key is the string the buyer types in. A key is 25 random characters in groups of 5, optionally behind a prefix such as PRO-. Lowercase letters and stray spaces are normalised before lookup.
The server never stores the key, only an HMAC-SHA256 hash of it. That is why a key is shown once, when it is created; after that the list shows only a preview like PRO-XXXXX-…-XXXXX. Create keys in Licensing & releases › Licenses with Create keys, then copy them or use Download .txt before clicking I've saved them.
License statuses:
- Unused: not activated yet. The term only starts at the first activation.
- Active: activated, with an expiry date or lifetime.
- Expired: past its expiry date. If the plan has grace days, the software keeps working for that long and reports the state
graceso you can warn the user. - Suspended: paused; Reinstate brings it back.
- Revoked: stopped for good; it cannot be reinstated.
Suspending or revoking a license ends its live sessions at once. More in Creating and managing licenses.
License plan (policy)
A license plan is the template a license is made from. The code calls it a policy, and the create-keys form labels it Plan. Create one in Licensing & releases › Sign-in & license plans, section License plans, with Add plan. A plan sets the term, machines, entitlements, trial, move rules, grace days, notice before the end, how long a silent machine keeps its seat, and sessions at once.
Each app has at most one plan marked Default for new keys and free accounts; marking another plan moves the mark. That plan is used when you create keys without choosing a plan, and when someone registers an account without a key.
The term and the number of machines are copied into each license when it is created, so editing the plan later does not change them on existing licenses. The other rules, such as entitlements, grace days and moves, are read from the plan directly, so changes reach licenses already issued.
Entitlement
An entitlement is a switch for one feature of your software, for example PDF export in the Pro edition only. You declare them per app in the Features box of the Sign-in & license plans page, with a Display name and a key made of lowercase letters, digits and underscores, such as export_pdf. Each license plan then grants a subset of that list.
The list travels inside the signed answer, so nobody can change it in transit. In your software, check it with clavis.has("export_pdf"); the list is refreshed on every heartbeat. See License plans and entitlements.
Device
A device is a machine that activated a license. The server recognises it by three things:
- Device key: an Ed25519 key pair the SDK generates on first run. Store it in the OS keychain so the machine keeps its identity.
- Fingerprint: a stable hash of the machine.
- Components: hashes of individual parts (CPU, board, disk...). When at least 3 of them match (the default), the server treats it as the same machine. Send more than that, so a reinstall or one replaced part does not cost a seat.
When a license already has all its machines, a new one is refused with device_limit. A machine that stays silent longer than the plan allows (72 hours when left empty) gives its seat back. A blocked machine is blocked across the whole app, whatever key it brings. See Devices, HWID and transfers.
Session
Every successful sign-in creates a session, ses_…. A session is bound to the device key that created it, so a session ID copied to another machine is useless (session_device_mismatch). A session lives 60 minutes and every heartbeat extends it, so call heartbeat() about every 30 minutes. With Short-Lived Session Lease turned on in Advanced Protection, a session lives only three times the heartbeat interval you set.
The plan's Sessions at once field caps how many places can run in parallel; signing in again on the same machine replaces that machine's old session. A session ends when the software calls logout(), when you click End session in End users › Devices & sessions, or when its license is suspended, revoked or has its devices reset.
End user
An end user signs in to your software with a username and password; they are not a dashboard member. End users only exist in the Account and Account + license key modes; in License key mode, the license itself is the identity.
Usernames are unique within an app, and passwords are stored as Argon2 hashes. When someone registers from your software, the account is always linked to a license: the key they entered, or, without a key, an internal license made from the default plan. A license already linked to an account cannot register another one (license_already_registered), and an account without a license is refused at sign-in (no_license). Manage them in End users › Users with Add user, Ban, Unban and Reset password. See End users.
Variable
A variable is a key and value your software receives after signing in: configuration, feature flags or messages without a new build. Add one in Integration › Variables with Add variable and choose a Scope: All users, One license or One user. When keys collide, the most specific value wins: user, then license, then global.
The CLV1 protocol
Your software talks to the server over CLV1. Each request is signed with the device key over the App ID, method, path, body hash, timestamp, a single-use nonce and the session ID. The server checks the signature, accepts at most 60 seconds of clock drift and refuses a nonce it has already seen (replayed_request). Every answer, errors included, is signed with the app's signing key and bound to the request's nonce, so it cannot be replayed or forged. The JavaScript SDK speaks CLV1.1, the extension that adds kid for key rotation. The full specification is in the CLV1 protocol.
Putting it together: one activation
import { ClavisClient, hashComponent } from "@clavisauh/sdk";
const clavis = new ClavisClient({
baseUrl: "https://api.example.com",
appId: "app_…", // the app
appPublicKey: "<public key>", // public half of the signing key
device: { fingerprint: hashComponent(machineId) }, // the device
deviceKey: await loadDeviceKey(), // device key kept in the keychain
});
const grant = await clavis.activate(licenseKey); // the license key
console.log(grant.session.id, grant.license.state); // session, license state
if (clavis.has("export_pdf")) enablePdfExport(); // entitlement from the plan
console.log(grant.variables); // variables
When activate() runs, the server:
- Checks the request's signature, clock and nonce, whether the app accepts sign-ins, and, in Advanced Protection, the access rules.
- Checks the sign-in mode, maintenance and the minimum version.
- Finds the license by the hash of the key and checks its status and expiry plus grace.
- Activates the license if it is Unused (the term starts now), recognises or adds the device, and checks the machine and session limits. If any of this is refused, the whole step is rolled back.
- Creates the session and returns a signed answer: session, license, entitlements, device, variables,
nextCheckSeconds, and an offline token unless Online-Only Mode is on. - Records the outcome, allowed or denied with a reason, in App security › Activity log.