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
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -66,6 +66,9 @@ if __name__ == "__main__":
66
66
|`on_failure`|`Callable[[str, Optional[Exception]], None] \| None`| no |`None`| Called on login/heartbeat/network failure; if omitted, process exits via `os._exit(1)`|
67
67
|`request_timeout`|`int`| no |`15`| HTTP timeout (seconds) |
68
68
|`ttl_seconds`|`int \| None`| no |`None` (server default: 86400) | Requested session token lifetime. Server clamps to `[3600, 604800]`; preserved across heartbeat refreshes. |
69
+
|`hwid_override`|`str \| None`| no |`None`| Optional custom HWID/subject string. When set to a non-empty value (for example `tg:123456789`), the SDK sends it instead of generating a machine fingerprint. |
70
+
71
+
For Telegram/Discord bot flows, prefer immutable IDs (`tg:<user_id>`, `discord:<user_id>`) instead of usernames.
|`request_timeout`| int |`15`| HTTP request timeout in seconds |
53
53
|`ttl_seconds`|`int \| None`|`None` (server default: 86400) | Requested session token lifetime. Server clamps to `[3600, 604800]`; preserved across heartbeat refreshes. |
54
+
|`hwid_override`|`str \| None`|`None`| Optional custom hardware/subject identifier. When set to a non-empty value, the SDK uses it instead of machine fingerprinting. |
55
+
56
+
### Identity-based binding example (Telegram/Discord)
57
+
58
+
```python
59
+
client = AuthForgeClient(
60
+
app_id="YOUR_APP_ID",
61
+
app_secret="YOUR_APP_SECRET",
62
+
public_key="YOUR_PUBLIC_KEY",
63
+
heartbeat_mode="SERVER",
64
+
hwid_override=f"tg:{telegram_user_id}", # or f"discord:{discord_user_id}"
65
+
)
66
+
```
54
67
55
68
## Billing
56
69
@@ -64,6 +77,7 @@ A desktop app running 6h/day at a 15-minute interval burns ~3–4 credits/day. A
64
77
| Method | Returns | Description |
65
78
|---|---|---|
66
79
|`login(license_key)`|`bool`| Validates key and stores signed session (`sessionToken`, `expiresIn`, `appVariables`, `licenseVariables`) |
80
+
|`self_ban(...)`|`dict`| Requests `/auth/selfban` to blacklist HWID/IP and optionally revoke (session-authenticated only) |
67
81
|`logout()`|`None`| Stops heartbeat and clears all session/auth state |
68
82
|`is_authenticated()`|`bool`| True when an active authenticated session exists |
69
83
|`get_session_data()`|`dict \| None`| Full decoded payload map |
@@ -81,7 +95,7 @@ A desktop app running 6h/day at a 15-minute interval burns ~3–4 credits/day. A
81
95
If authentication fails (login rejected, heartbeat fails, signature mismatch, etc.), the SDK calls your `on_failure` callback if one is provided. If no callback is set, **the SDK calls `os._exit(1)` to terminate the process.** This is intentional — it prevents your app from running without a valid license.
- Uses post-session mode when a session token is available (`session_token` arg or current SDK session).
143
+
- Falls back to pre-session mode using `license_key` + nonce + app secret.
144
+
- In pre-session mode, revoke is forced off client-side to avoid unsafe key revocations.
145
+
108
146
## How It Works
109
147
110
-
1.**Login** — Collects a hardware fingerprint (MAC, CPU, disk serial), generates a random nonce, and sends everything to the AuthForge API. The server validates the license key, binds the HWID, deducts a credit, and returns a signed payload. The SDK verifies the Ed25519 signature and nonce to prevent replay attacks.
148
+
1.**Login** — Uses `hwid_override` if provided; otherwise collects a hardware fingerprint (MAC, CPU, disk serial). It then generates a random nonce and sends everything to the AuthForge API. The server validates the license key, binds the HWID, deducts a credit, and returns a signed payload. The SDK verifies the Ed25519 signature and nonce to prevent replay attacks.
111
149
112
150
2.**Heartbeat** — A background daemon thread checks in at the configured interval. In SERVER mode, it sends a fresh nonce and verifies the response. In LOCAL mode, it re-verifies the stored signature and checks expiry without network calls.
113
151
@@ -122,6 +160,8 @@ The SDK generates a deterministic hardware fingerprint by hashing:
122
160
123
161
Each component falls back gracefully if it can't be read (e.g. permissions issues). The HWID is sent with every auth request so the server can enforce per-device license limits.
124
162
163
+
For non-device identities (for example Telegram users), pass `hwid_override` such as `tg:<user_id>`.
164
+
125
165
## Test Vectors
126
166
127
167
The shared `test_vectors.json` file validates cross-language Ed25519 verification behavior.
0 commit comments