Skip to main content

Apps

An app represents the software you’re protecting. Each app has:
  • App ID: A UUID that identifies your app. Public (embedded in your binary).
  • App Secret: A UUID used to authenticate /auth/validate requests. Keep this secret. Rotatable via the dashboard.
  • Public Key: A base64 Ed25519 public key used by SDKs to verify signed /auth/validate and /auth/heartbeat success responses.
  • Settings: Configuration for your app (variables, security rules, webhooks).
You can create multiple apps under one account. Each app has its own license keys, variables, and security settings.

License Keys

License keys are alphanumeric strings in the format XXXX-XXXX-XXXX-XXXX (using A–Z excluding I and O, digits 2–9). Each key is bound to a single app. A license has the following properties: Generate keys in the dashboard or programmatically via the Developer API.

HWID (Hardware ID)

A hardware fingerprint of the user’s machine. Each SDK collects stable system identifiers (such as MAC address, CPU, hostname, or disk serial; varying by language and platform) and computes a SHA-256 hash. The result is a 64-character hex string. The exact inputs differ per SDK to use the most reliable identifiers available in each language’s standard library. The backend treats the HWID as an opaque string; it only needs to be stable and unique per machine. Important: HWID strings are SDK-specific. The same physical computer can produce different HWIDs when using different AuthForge SDKs (for example, Python vs C#). See Hardware locking (HWID) for how that affects seats, support, and security lists. The HWID is sent during license validation. If the license hasn’t seen this HWID before and has available slots, the server binds it. If all slots are full and the HWID doesn’t match any bound device, authentication fails with hwid_mismatch.

HWID Slots

The number of machines a single license key can be active on simultaneously. When a user authenticates from a new device:
  • If there’s an open slot, the HWID is bound automatically.
  • If all slots are full, authentication fails.
To let a customer move to a new machine, reset their HWID bindings from the dashboard or via the API (reset-hwid action). HWID resets and blacklists take effect at the next online check-in for apps with check-ins enabled, and at session expiry (up to the configured TTL) otherwise.

Credits

Credits are the unit of billing in AuthForge. Every billable operation deducts credits from your account. Heartbeats only occur if you enable online check-ins. Heartbeat billing is debited on every 10th successful heartbeat. Heartbeat credits are not prepaid; the session itself is short-lived (see Session TTL), so “every 10th heartbeat” is literally how many billable events happened. Purchase credits in the dashboard. Available tiers: Set up auto-refill to automatically purchase credits when your balance drops below a threshold.

Activation and the Grace Period

Authentication in AuthForge is one online call followed by a window of local operation:
  1. Activate (validate): On login, the SDK sends POST /auth/validate. The server binds the HWID, checks revocation, expiry, and credits, and returns an Ed25519-signed session.
  2. Grace period: The app then keeps running on that signed session without contacting AuthForge. The SDK periodically re-verifies the stored session signature locally (no network calls) and stops when the session expires.
The grace period equals the session TTL: 24 hours by default, clamped by the server to a minimum of 1 hour and a maximum of 7 days, and configurable via the SDK’s ttl option (ttl_seconds / ttlSeconds / SessionTTL / session_ttl_seconds depending on language). When the session expires, the SDK triggers your onFailure callback (or terminates the process if no callback is set), and the user must activate again. This is the default experience: activate online once, then run through the grace period with zero further network traffic and zero heartbeat credit consumption.

Online Check-ins (Optional)

If you need faster revocation or concurrent-use detection, opt in to online check-ins: periodic POST /auth/heartbeat calls while the app runs. Enable them with the SDK’s online_heartbeat / onlineHeartbeat / OnlineHeartbeat option. On each interval (default 15 minutes, 900 seconds), the SDK sends the session token to /auth/heartbeat. The server verifies the token + signature chain, checks the license status, re-checks that this device’s HWID is still bound (unless the license has unlimited seats) and that the HWID and current IP pass the app’s blacklists/whitelists, and returns a new signed response that refreshes the session. SDKs verify every heartbeat signature with your app’s Ed25519 public key. If a check-in gets a definitive answer (the license was revoked or expired, the HWID is no longer bound, the HWID or IP is blocked, or the session is invalid), the SDK clears the stored session, stops check-ins, and then triggers your onFailure callback (or terminates the process if no callback is set). Transient failures such as network errors, timeouts, rate_limited, or system_error are reported to onFailure with a transient classification and check-ins continue (with no callback set, the SDK writes a one-line warning to stderr instead); see Check-in and session failure handling. Trade-offs:
  • Revocations take effect on the next check-in instead of at session expiry: real-time enforcement for high-value software.
  • Each successful check-in refreshes the session, so long-running apps never hit the grace-period expiry.
  • Requires network connectivity while the app runs.
  • Billing: 1 credit per 10 heartbeats. The server rate-limits heartbeats to 6 per minute per license, so keep the interval at 10 seconds or more; the 15-minute default is right for most apps.
Migrating from heartbeat_mode: older SDK versions exposed heartbeat_mode: "SERVER" | "LOCAL". The default grace-period behavior is what "LOCAL" used to do (just remove the option), and online check-ins are what "SERVER" used to do (enable online_heartbeat). The old option still works but is deprecated.

Offline License Files (.authforge)

The grace period is not offline licensing: it continues a session after an online activation and lapses within at most 7 days. For machines that can never reach AuthForge, there is a separate mode: offline license files. An operator mints a .authforge file in the dashboard (or via POST /v1/licenses/{licenseKey}/offline-files). The file is a standalone document signed with your app’s existing Ed25519 key. On the air-gapped machine the SDK verifies it with only your app public key and the machine’s HWID (loginFromFile), and never contacts AuthForge. Because a distributed file cannot be revoked, mint short-lived, HWID-bound files and re-issue on a schedule. Full details, format and SDK examples: Offline license files. Operational guidance: Offline licensing best practices.

Session Tokens

A successful /auth/validate response includes a signed session token that the SDK stores, re-verifies locally during the grace period, and replays on every online check-in (if enabled). The token carries the HWID binding, license key, and (if the SDK requested a custom lifetime) a ttl claim. SDKs expose a ttlSeconds / session_ttl_seconds / SessionTTL configuration option so you can tune the grace period: how long the SDK can keep running without reaching the server before forcing a re-login. The server silently clamps out-of-range values to the 1 hour to 7 day range.

Signed payload fields

Successful /auth/validate and /auth/heartbeat responses include a signed JSON payload (base64 in the payload field) in addition to the nested session JWT in sessionToken. Besides appVariables / licenseVariables on validate, the payload includes: Heartbeats repeat the entitlement fields when applicable so long-running clients see updates (for example if an admin changes seats or expiry) without calling validate again.

Developer API

A server-to-server REST API for automating license management from your own backend. Authenticated with API keys (prefixed af_live_). Use the Developer API to:
  • Create licenses programmatically (e.g., after a Stripe payment)
  • Revoke, activate, extend, or reset HWID on licenses
  • List and query licenses
  • Manage app variables, webhooks, and security settings
See the API Reference for full documentation.

App Variables

Key-value pairs set per app, delivered to every SDK client during authentication in the appVariables field of the signed payload. Use cases:
  • Feature flags: "maintenanceMode": true
  • Remote config: "maxUploadSizeMb": 50
  • Messages: "motd": "v2.0 releasing Friday!"
  • Version gating: "minVersion": "1.5.0"
Limits: max 50 keys, 4 KB total, flat values only (string, number, or boolean). Set via the dashboard or the Variables API.

License Variables

Key-value pairs set per license, delivered only to that specific license holder during authentication in the licenseVariables field. Use cases:
  • Plan tiers: "plan": "pro"
  • Per-user limits: "maxProjects": 10
  • Custom metadata: "customerName": "Acme Corp"
Same limits as app variables. Set via the dashboard or the Variables API.

Webhooks

Real-time HTTP notifications sent to your server when license events occur. Each delivery is HMAC-SHA256 signed with your webhook secret for verification. Supported events: Max 5 webhooks per app. See Webhooks for setup and verification details.

Blacklists & Whitelists

Per-app access control lists for HWIDs and IP addresses:
  • HWID blacklist: Block specific hardware IDs from authenticating.
  • HWID whitelist: When set, only listed HWIDs can authenticate (allowlist mode).
  • IP blacklist / whitelist: Same concept for IP addresses.
Blacklist takes precedence over whitelist. Max 500 entries per list. HWID resets and blacklists take effect at the next online check-in for apps with check-ins enabled, and at session expiry (up to the configured TTL) otherwise. See Security for configuration details.