The CLV1 protocol is now publicRead the spec
Browse the library

Documentation librarySecurity

Protect 24/7

Protect 24/7 watches every request your software sends to ClavisAUH, recognises 12 signs of attack or abuse, scores the risk of each license, device and IP, and groups what it sees into incidents that you handle, or that it handles on its own at thresholds you set.

11 min read

What Protect watches

Protect runs for every app, in both protection modes; there is nothing to switch on. When a request looks wrong, the server records a security event with one of 12 signals, tied to the license, device and IP involved whenever it can tell which they are. In Standard Protection that is all it does: there is no bell notification, no email or chat alert and no automatic response. Those need Advanced Protection.

SignalRaised whenSeverityWeight
Forged signatureA request signature does not match the device key (bad_signature), or the SDK reports answers that failed its verification (a fake server or a tampering proxy)High18
Replayed requestA nonce that was already used comes back (replayed_request)High16
Clock driftThe request time is more than 5 minutes off server time. Anything more than 60 seconds off is refused with clock_skew either wayMedium6
Key brute-forcingOne IP gets a key or password wrong for the 20th time within 15 minutes; after that the IP receives too_many_attemptsHigh14
Key sharingA machine is refused because the key is full (device_limit), or a session id is used from another machine (session_device_mismatch)High15
Impossible travelThe same license signs in from another country, on another machine, within 30 minutesMedium10
Session overflowA sign-in is refused because the session cap on the license plan is reached (session_limit)Medium8
Unknown buildThe software sends a buildHash that matches no file in the app's releases, once the app has at least one published releaseHigh15
Tampering detectedYour software reports a debugger, hook, virtual machine or patched file through the SDKLow4
Blocked by an access ruleA request is stopped by an access rule, in Advanced ProtectionLow3
Offline clock rollbackYour software reports, through the SDK, that the clock was turned back while offlineMedium8
Denial spikeRefusals in the last hour reach 20 or more and sit far above the app's usual hourly rate over 14 daysMedium6

A few things to know:

  • Impossible travel and the country column only have data when the API server receives the request's country. Without it, the country shows as ··.
  • Denial spike is checked at most once every 10 minutes per app and is not tied to any license, device or IP.
  • For the same app, signal and source (IP, license or device), Protect stores at most 30 events a minute. The rest are dropped, so a flood cannot bury your data.

Feeding signals from your software

The server and the SDK detect most signals by themselves. Two things are worth adding on your side: send the hash of the running build so Protect can spot unknown builds, and report what your software detects.

import { ClavisClient } from "@clavisauh/sdk";

const clavis = new ClavisClient({
  baseUrl: "https://api.example.com",
  appId: "app_…",
  appPublicKey,
  device,
  appVersion: "2.3.0",
  buildHash, // SHA-256 of the running file, 64 lowercase hex characters
});

// Your software found a debugger: tell Protect. Needs a live session.
await clavis.request("/v1/client/report", { kind: "debugger", detail: { tool: "x64dbg" } });

kind takes debugger, hook, vm, patched (all Tampering detected) and offline_rewind (Offline clock rollback). The response_verification report (Forged signature) is sent by the JS SDK itself after the next verified answer, so you never call it. detail holds short keys with string (up to 200 characters), number or boolean values.

Risk scores

Each event adds the signal's weight to the score of every subject involved. Licenses, devices and IPs are scored separately.

  • One signal type can add at most 5 times its weight: Forged signature tops out at 90, Tampering detected at 20. The total is capped at 100.
  • A score halves for every 24 hours without a new signal.
  • Under 40 is Normal, 40 to 69 is Watch, 70 and up is Danger. The meter goes from grey to amber to red.

Example: a cracked copy sends 25 badly signed requests. Forged signature hits its cap of 90 and the license is in Danger. If it then goes quiet, the score is 45 after 24 hours and about 23 after 48, and it drops off the Needs you list.

Scores appear in the Needs you list, the incident drawer, the Sources panel (for IPs) and the license detail panel. The license panel shows the score as of the latest signal, before decay.

Incidents

Protect groups events into incidents so you never read them one by one:

  • A new event joins an incident that is not closed, has the same signal and the same main subject, and saw an event in the last 30 minutes. Otherwise a new incident opens.
  • The main subject is the license when known, else the device, else the IP. Denial spike incidents show No single subject.
  • An incident carries the signal's severity and counts its events. Every new incident sends the security.incident webhook, in either mode.
  • In Advanced Protection, every new High incident adds a bell notification for the Owners and Admins. While the workspace has no alert rules, it also emails them, at most once every 5 minutes. As soon as you create a rule of your own (even a disabled one), only your rules apply. See Alerts and channels.

Handling an incident

  1. Click an incident under Open incidents, or a row in Live events. The drawer opens and the URL gains ?incident=…, a link you can send to a teammate.
  2. Subject names the license, device or IP with its risk score, and offers Suspend or Reinstate, Block device or Unblock, and Block IP.
  3. Why lists the signals behind the score with estimated counts. What was done lists the last 20 actions on the subject, each marked Automatic or By hand. Timeline shows the 50 latest events with IP, machine name and API path when there is one.
  4. Click Take it so your team knows you are on it; the incident moves to In hand.
  5. Write what you checked and decided in Note, then click Close incident. The note is required, at least 3 characters.

A closed incident has a Reopen button and takes no new events; the next signal of that kind opens a new incident.

The Overview tab

Open App security › Protection. The status line under the title shows Watching, the app's mode (click it to go to the Methods tab) and, in Advanced Protection, either Auto-response on or Alerts only.

  • Time range: 1 h, 24 h, 7 d, 30 d. Filters for Country, Signal and Version, plus Clear. The range, the filters and the open incident all live in the URL.
  • Four tiles: Live sessions (updated every 2 seconds), Signed requests per minute (average of the last 5 minutes), Security events (events in the range, with how many subjects need you) and Protection mode with how many methods are on; see The two protection modes.
  • Security events over time: stacked bars in five families: Forgery (Forged signature, Replayed request, Offline clock rollback), Key abuse (Key brute-forcing, Key sharing, Session overflow), Time & place (Clock drift, Impossible travel), Tampering (Unknown build, Tampering detected), Rules & spikes (Blocked by an access rule, Denial spike). Each bar covers 5 minutes, 1 hour, 6 hours or 1 day depending on the range.
  • Sources: the 8 countries with the most events (click one to filter by it) and the 6 Most suspicious IPs with their risk score, marked Blocked while blocked.
  • Live events: the 40 newest events, pushed every 2 seconds. If the stream drops, the status reads Every 10 seconds while the page polls instead. Hover the list to get Paused; new events wait and appear when the pointer leaves.

Everything else refreshes every 30 seconds. With no events, incidents or subjects needing you, the page shows No security events yet with three shortcuts: Set up alerts (in Standard, Turn on Advanced Protection), Set transfer rules and Read the Protect guide.

Needs you, and acting by hand

The Needs you list holds up to 30 subjects whose score, after decay, is 40 or more and who had a signal in the last 3 days, highest first. Each row shows the license preview, machine name or IP, a suspended or blocked tag, the top three reasons (such as "3× forged") and the latest country. View next to a license opens its detail panel in Licensing & releases › Licenses.

Every action opens a dialog that asks for a Reason (at least 3 characters), recorded in the audit log. Every workspace role (Owner, Admin, Member) can use them.

ButtonWhereEffectYour software gets
SuspendNeeds you, incident drawerThe license is suspended and every session ends nowsession_expired, then license_suspended on the next sign-in
ReinstateIncident drawer, for a suspended licenseThe license works again right awayNormal service
Block deviceNeeds you, incident drawerThe machine stays out of the app whatever key it brings; its sessions enddevice_blocked
UnblockIncident drawer, for a blocked deviceThe machine may sign in againNormal service
Block IPNeeds you, incident drawerEvery request from that IP to the app is refused, lifting by itself after 24 hoursaccess_blocked
Lift blockBlocked IP addresses on the Access Rules tabThe IP may connect again right awayNormal service
DismissNeeds youThe risk score goes back to 0; events stay on recordNo change
UndoWhat was done in the incident drawerReverses one suspension, device block or IP blockAs before the action
  • Ended sessions cannot be undone; the software simply signs in again.
  • IP blocks apply in both protection modes. To lift one early, use Lift block, or Undo on the IP block under What was done. Otherwise the block expires after 24 hours.

Your software should tell an ended session apart from a hard block:

import { ClavisError } from "@clavisauh/sdk";

try {
  await clavis.heartbeat();
} catch (err) {
  if (!(err instanceof ClavisError)) throw err;
  if (err.code === "session_expired") return showSignIn(); // session ended, for example by Protect
  if (["license_suspended", "device_blocked", "access_blocked"].includes(err.code)) return lockApp(err.code);
  throw err;
}

Graduated Enforcement

Graduated Enforcement sits in the Detection and Response group of App security › Protection, tab Methods. It only runs in Advanced Protection and is off by default. Only Owners and Admins can change it.

  1. Turn on the Graduated Enforcement switch.
  2. Pick Alerts only or Act on its own.
  3. Enter the Alert at, Sign out at and Suspend at thresholds, from 10 to 100. Each field saves when you leave it.
ThresholdDefaultWhen a score reaches it
Alert at40Records an Alerted action on the main subject, once each time the score crosses the line
Sign out at60Every session of the license ends and the user must sign in again
Suspend at80An active license is suspended and every session ends

In Act on its own mode, Protect also blocks a device when that same machine repeats Key sharing or Unknown build within a short time, and blocks an IP for 24 hours when it raises Key brute-forcing.

Alerts only does just the first row of the table. Alerted is a record and a webhook; emails and chat messages come from your alert rules, independently of this method. Act on its own runs on Premium: on Basic the mode still only alerts, and the page says "Acting on its own runs on Premium, your plan alerts only". With the switch off, nothing happens automatically.

Every automatic action appears under What was done marked Automatic with the score at the time, is written to the audit log and sends the security.action webhook. Actions taken by hand do not send security.action.

The All Apps tab

Monitoring & alerts › Security, tab All Apps, puts every app on one screen and refreshes every 30 seconds:

  • Three tiles: Signals in 24 h, Open incidents, Apps in Advanced.
  • The app table: each app with its mode, Signals 24h, open Incidents and Top risk (the highest stored score of any subject with a signal in the last 3 days). Click a row to open that app's Protection page.
  • Latest incidents: the 8 most recently active open incidents across all apps; click one to open its drawer directly.

Signal counts on this page always cover the last 24 hours, whatever your plan.

History window by plan

LimitBasicPremium
Protect window1 day (1 h, 24 h)30 days (all four ranges)
Protect auto-responseNoYes
Discord, Telegram and webhook alert channelsNo, email onlyYes

Picking a range longer than your plan allows is not an error: the data is cut to the longest allowed range and the page says "Your plan shows up to 24 h". The Needs you list (3 days) and Open incidents are not limited by the window. The values for your workspace are in Account & organization › Plan & usage, rows Protect window (days) and Protect auto-response. See Basic, Premium and limits.

How can we help?

Frequently asked

What is ClavisAUH?

A licensing and authentication service for desktop software: license keys, device binding, end-user sign-in and signed responses. All run from one dashboard

Why can't a cracker fake your server?

The SDK only trusts answers signed with your app's private key. That key never leaves our servers, so a fake server can't sign and gets rejected

What ends up in my binary?

Your app id and public key. Nothing secret, because each device makes its own key pair on first run

Does it work offline?

Yes. Every plan gets a signed offline token for 7 days, and your app checks it locally. Premium lets you choose how long. A revoked license can keep working offline for that time, unless Online-Only Mode is on

Which languages are supported?

JavaScript and TypeScript today. C++, C# and Python are next, on the same open protocol

Is Basic really free?

Yes. No time limit, no card. Move to Premium when you need more

Get in touch