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.
| Signal | Raised when | Severity | Weight |
|---|---|---|---|
| Forged signature | A 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) | High | 18 |
| Replayed request | A nonce that was already used comes back (replayed_request) | High | 16 |
| Clock drift | The request time is more than 5 minutes off server time. Anything more than 60 seconds off is refused with clock_skew either way | Medium | 6 |
| Key brute-forcing | One IP gets a key or password wrong for the 20th time within 15 minutes; after that the IP receives too_many_attempts | High | 14 |
| Key sharing | A machine is refused because the key is full (device_limit), or a session id is used from another machine (session_device_mismatch) | High | 15 |
| Impossible travel | The same license signs in from another country, on another machine, within 30 minutes | Medium | 10 |
| Session overflow | A sign-in is refused because the session cap on the license plan is reached (session_limit) | Medium | 8 |
| Unknown build | The software sends a buildHash that matches no file in the app's releases, once the app has at least one published release | High | 15 |
| Tampering detected | Your software reports a debugger, hook, virtual machine or patched file through the SDK | Low | 4 |
| Blocked by an access rule | A request is stopped by an access rule, in Advanced Protection | Low | 3 |
| Offline clock rollback | Your software reports, through the SDK, that the clock was turned back while offline | Medium | 8 |
| Denial spike | Refusals in the last hour reach 20 or more and sit far above the app's usual hourly rate over 14 days | Medium | 6 |
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.incidentwebhook, 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
- 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. - Subject names the license, device or IP with its risk score, and offers Suspend or Reinstate, Block device or Unblock, and Block IP.
- 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.
- Click Take it so your team knows you are on it; the incident moves to In hand.
- 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.
| Button | Where | Effect | Your software gets |
|---|---|---|---|
| Suspend | Needs you, incident drawer | The license is suspended and every session ends now | session_expired, then license_suspended on the next sign-in |
| Reinstate | Incident drawer, for a suspended license | The license works again right away | Normal service |
| Block device | Needs you, incident drawer | The machine stays out of the app whatever key it brings; its sessions end | device_blocked |
| Unblock | Incident drawer, for a blocked device | The machine may sign in again | Normal service |
| Block IP | Needs you, incident drawer | Every request from that IP to the app is refused, lifting by itself after 24 hours | access_blocked |
| Lift block | Blocked IP addresses on the Access Rules tab | The IP may connect again right away | Normal service |
| Dismiss | Needs you | The risk score goes back to 0; events stay on record | No change |
| Undo | What was done in the incident drawer | Reverses one suspension, device block or IP block | As 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.
- Turn on the Graduated Enforcement switch.
- Pick Alerts only or Act on its own.
- Enter the Alert at, Sign out at and Suspend at thresholds, from 10 to 100. Each field saves when you leave it.
| Threshold | Default | When a score reaches it |
|---|---|---|
| Alert at | 40 | Records an Alerted action on the main subject, once each time the score crosses the line |
| Sign out at | 60 | Every session of the license ends and the user must sign in again |
| Suspend at | 80 | An 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
| Limit | Basic | Premium |
|---|---|---|
| Protect window | 1 day (1 h, 24 h) | 30 days (all four ranges) |
| Protect auto-response | No | Yes |
| Discord, Telegram and webhook alert channels | No, email only | Yes |
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.