You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@
7
7
8
8
AuthForge is a license key validation service. Your app activates by sending a license key + hardware ID to `POST /auth/validate`; the server checks revocation, expiry, HWID binding, and credits, then returns an Ed25519-signed session with a TTL. By default the app then runs through the **grace period**: it keeps running on the signed session with no network calls, and a background check fails when the session TTL expires. Optionally, enable **online check-ins** (`online_heartbeat=True`): periodic `POST /auth/heartbeat` calls for fast revocation and concurrent-use detection. If the license is revoked or expired, the check-in fails and you handle it (typically exit the app).
9
9
10
-
There is also a **separate** mode for machines that can never reach the internet: **offline license files (`.authforge`)**. The operator mints a signed file in the AuthForge cloud; `login_from_file()` verifies it locally with the app public key and the machine HWID, with zero network calls. Do not ship the App Secret in those builds (`app_secret=None`). Only use it when the user explicitly asks for air-gapped / offline-file licensing. The default integration is always online `login()` + grace period.
10
+
There is also a **separate** mode for machines that can never reach the internet: **offline license files (`.authforge`)**. The operator mints a signed file in the AuthForge cloud; `login_from_file()` verifies it locally with the app public key and the machine HWID, with zero network calls. Do not ship the App Secret in those builds (`app_secret=None`). Only use it when the user explicitly asks for air-gapped / offline-file licensing. The default integration is always online `login()` + grace period. To collect the HWID for a bound file, write an **activation request** (`.authforge-request`) with `create_activation_request` / `write_activation_request`. It is not a license, is not signed, and does not mint anything. Prefer it over printing the raw HWID.
11
11
12
12
## Billing model (so you can pick sensible intervals)
13
13
@@ -97,6 +97,8 @@ The attribute `client.heartbeat_mode` still exists for back-compat and reflects
97
97
|`get_offline_license()`|`dict \| None`|`jti`, `expires_at`, `hwid_policy`, … of the offline file in use |
98
98
|`get_session_kind()`|`"online" \| "offline" \| None`| Kind of session the client holds; `None` when logged out |
99
99
|`get_hwid()`|`str`| HWID this client sends; the customer reports it so the operator can mint a bound file |
100
+
|`create_activation_request(**kwargs)`|`str`| Unsigned `.authforge-request` for this machine. No network, no secret, callable before `login()`. Hostname omitted unless `include_machine_name=True`|
101
+
|`write_activation_request(path, **kwargs)`|`None`| Writes that file as UTF-8 |
100
102
|`logout()`|`None`| Stops background checks and clears session state |
101
103
|`is_authenticated()`|`bool`| Whether a session token is present and marked authenticated |
102
104
|`get_session_data()`|`dict \| None`| Decoded signed payload map |
# 2. Later, authorize from the minted file (path or armored text). No network.
158
158
if client.login_from_file("license.authforge"):
@@ -204,6 +204,8 @@ A desktop app running 6h/day with online check-ins at a 15-minute interval burns
204
204
|`get_offline_license()`|`dict \| None`| Metadata of the offline file in use (`jti`, `expires_at`, `hwid_policy`, …) |
205
205
|`get_session_kind()`|`"online" \| "offline" \| None`| Which kind of session the client holds (`None` when logged out) |
206
206
|`get_hwid()`|`str`| The HWID this client sends (or `hwid_override`); customers share it to receive a bound file |
207
+
|`create_activation_request(**kwargs)`|`str`| Unsigned `.authforge-request` for this machine. No network, no secret. Hostname omitted unless `include_machine_name=True`|
208
+
|`write_activation_request(path, **kwargs)`|`None`| Writes that file as UTF-8 |
207
209
|`logout()`|`None`| Stops background checks and clears all session/auth state |
208
210
|`is_authenticated()`|`bool`| True when an active authenticated session exists |
209
211
|`get_session_data()`|`dict \| None`| Full decoded payload map |
"description": "Cross-SDK conformance vectors for activation requests (.authforge-request). Generators with the same inputs must match good_minimal and good_full byte-for-byte. Parser tolerance: CRLF, UTF-8 BOM, re-wrapping, email preamble. Checksum is decision-relevant.",
0 commit comments