Skip to content

Commit bd4d3e9

Browse files
committed
Session TTL & Heartbeats redesign
1 parent 35284a9 commit bd4d3e9

3 files changed

Lines changed: 520 additions & 494 deletions

File tree

AGENTS.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77

88
AuthForge is a license key validation service. Your app sends a license key + hardware ID to the AuthForge API, gets back a cryptographically signed response, and runs background heartbeats to maintain the session. If the license is revoked or expired, the heartbeat fails and you handle it (typically exit the app).
99

10+
## Billing model (so you can pick sensible intervals)
11+
12+
- **1 `login()` = 1 credit** (one `/auth/validate` debit).
13+
- **10 heartbeats = 1 credit** (billed on every 10th successful heartbeat per license).
14+
- Any `heartbeat_interval` is safe — from `1` (server apps) to `900` (15 min, desktop apps). Revocations always take effect on the **next** heartbeat regardless of interval.
15+
1016
## Installation
1117

1218
Copy `authforge.py` into your project (single file, stdlib only). Requires Python 3.9+.
@@ -55,10 +61,11 @@ if __name__ == "__main__":
5561
| `app_id` | `str` | yes || Application ID |
5662
| `app_secret` | `str` | yes || Application secret |
5763
| `heartbeat_mode` | `str` | yes || `"SERVER"` or `"LOCAL"` (case-insensitive) |
58-
| `heartbeat_interval` | `int` | no | `900` | Seconds between heartbeats |
64+
| `heartbeat_interval` | `int` | no | `900` | Seconds between heartbeats (any value ≥ 1) |
5965
| `api_base_url` | `str` | no | `https://auth.authforge.cc` | API base URL |
6066
| `on_failure` | `Callable[[str, Optional[Exception]], None] \| None` | no | `None` | Called on login/heartbeat/network failure; if omitted, process exits via `os._exit(1)` |
6167
| `request_timeout` | `int` | no | `15` | HTTP timeout (seconds) |
68+
| `ttl_seconds` | `int \| None` | no | `None` (server default: 86400) | Requested session token lifetime. Server clamps to `[3600, 604800]`; preserved across heartbeat refreshes. |
6269

6370
## Methods
6471

@@ -75,6 +82,9 @@ if __name__ == "__main__":
7582

7683
invalid_app, invalid_key, expired, revoked, hwid_mismatch, no_credits, blocked, rate_limited, replay_detected, session_expired, app_disabled, bad_request
7784

85+
Notes:
86+
- `rate_limited` and `replay_detected` can only be returned from `/auth/validate`. Heartbeats are not IP rate-limited and do not enforce nonce replay.
87+
7888
## Common patterns
7989

8090
### Reading license variables (feature gating)

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,18 @@ else:
4242
| `app_secret` | str | required | Your application secret from the AuthForge dashboard |
4343
| `public_key` | str | required | App Ed25519 public key (base64) from dashboard |
4444
| `heartbeat_mode` | str | required | `"SERVER"` or `"LOCAL"` (see below) |
45-
| `heartbeat_interval` | int | `900` | Seconds between heartbeat checks (default 15 min) |
45+
| `heartbeat_interval` | int | `900` | Seconds between heartbeat checks (any value ≥ 1; default 15 min) |
4646
| `api_base_url` | str | `https://auth.authforge.cc` | API endpoint |
4747
| `on_failure` | callable | `None` | Callback `(reason: str, exc: Exception | None)` on auth failure |
4848
| `request_timeout` | int | `15` | HTTP request timeout in seconds |
49+
| `ttl_seconds` | `int \| None` | `None` (server default: 86400) | Requested session token lifetime. Server clamps to `[3600, 604800]`; preserved across heartbeat refreshes. |
50+
51+
## Billing
52+
53+
- **1 `login()` call = 1 credit** (one `/auth/validate` debit).
54+
- **10 heartbeats on the same license = 1 credit** (billed every 10th successful heartbeat).
55+
56+
A desktop app running 6h/day at a 15-minute interval burns ~3–4 credits/day. A server app running 24/7 at a 1-minute interval burns ~145 credits/day — pick the interval based on how fast you need revocations to propagate (they always land on the **next** heartbeat).
4957

5058
## Methods
5159

0 commit comments

Comments
 (0)