Skip to content
ABRQ DATADocs Abrq DIP · latest
Product page Request a trial
On this page

How Licensing Works

The license in one paragraph#

Abrq DIP is licensed with a vendor-signed JSON file placed on the host that runs the platform. The backend verifies the file's cryptographic signature at startup when running in production mode, and re-checks it once an hour in the background. There is no activation server, no phone-home, and no usage metering — verification is entirely offline against a vendor public key embedded in the release build.

The license file#

The license is a plain JSON envelope:

{
  "payload": {
    "license_id": "abrq-license-XXXX",
    "customer": "Example Customer",
    "issued_at": "2026-01-01T00:00:00+00:00",
    "expires_at": "2027-01-01T00:00:00+00:00",
    "features": [],
    "fingerprints": []
  },
  "signature": "<BASE64URL_SIGNATURE>"
}
  • The signature is an RSA-PSS signature (RSA-2048, MGF1-SHA256) over the canonical JSON of payload (sorted keys, compact separators).
  • It is verified against a vendor public key embedded in the shipped build. The matching private key never leaves the vendor — a license file cannot be minted or altered on the customer side.
  • The file is not a JWT and is never uploaded through the API. It lives on disk at the path given by ABRQ_LICENSE_FILE (default /var/abrq-dip/license.json).

What each payload field means — and what is deliberately not in the payload (no seat caps, no pipeline caps, no capacity entitlements) — is covered in Entitlements.

Verification at startup#

With ABRQ_ENV=prod, the backend refuses to start unless the license file exists, parses, carries a valid signature, has not expired, and (when hardware-bound) matches this host's fingerprint. A failed check surfaces as a startup error (License check failed: …) with an operator-actionable message — see Installing a license for the exact messages and log lines.

Note. Outside prod (ABRQ_ENV=dev or test) the license check is skipped — loudly. The backend logs a WARNING event license_check_bypassed with the note that deployments must run with ABRQ_ENV=prod to enforce licensing. The bypass is never silent.

After startup, an hourly background task (abrq_dip.license.recheck) re-reads the local file, logs the outcome, and updates Prometheus gauges (abrq_license_days_remaining, abrq_license_load_failed, abrq_license_enforcement_active). It only ever reads the local file — nothing is sent anywhere.

Where to see license state#

Two surfaces, same information:

  • Settings → License & Backup — the License card shows the customer name, license id, issue and expiry dates, days remaining, licensed features, and whether the license is hardware-bound. Admin-only (all Settings tabs are).
  • GET /api/v1/license — available to any authenticated user (viewer and up). Returns status (ok, dev, or error), customer, license_id, issued_at, expires_at, days_remaining, features, is_bound, and fingerprints_count. The signature is never returned. In dev/test the endpoint returns status: "dev" with all features enabled.
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \
  https://dip.example.com/api/v1/license

Expiry banners#

The web UI shows a non-dismissible banner as expiry approaches:

Days remaining Banner tier
30 or fewer Warning
7 or fewer Critical
0 / expired (or license error) Expired

These banners are the warning system — there is no grace period after expiry (a deliberate decision; see Expiry and clock integrity). The backend also logs license_expiry_approaching once days remaining drop below 30, and an optional expiry alert channel can page your team — see Notifications.

Renewal#

Renewal is a file swap, not a procedure:

  1. Obtain the renewed license.json from Abrq.
  2. Replace the file at the configured license path.
  3. Restart the backend API, worker, and beat processes.

The restart matters: the licensed feature set is cached for the lifetime of each process, so a replaced file is not picked up for feature gating until the processes restart. Per-path placement details are in Installing a license.