Sessions & Bindings
GeckoGuard tracks two types of associations between licenses and devices: bindings (persistent device records) and sessions (active usage tracking).
Bindings
Bindings are persistent records of devices (HWIDs) and IPs that have been associated with a license. They are created automatically during license authorization.
Binding Types
| Type | Description |
|---|---|
HWID | Hardware ID binding — tracks which devices have used the license |
IP | IP address binding — tracks which IPs have used the license |
Binding Behavior by Policy Mode
| Mode | Behavior |
|---|---|
unlimited | Bindings are recorded but not enforced |
sticky | First binding is permanent — subsequent different values are denied |
limit | Up to maxDistinct unique bindings allowed |
Binding Fields
Each binding tracks:
valueHash— SHA-256 hash of the HWID/IPregion— Country code (for IP bindings with region-based limiting)firstSeenAt— When this binding was first createdlastSeenAt— Most recent authorization using this bindingrevokedAt— If the binding has been reset/revoked
Resetting Bindings
HWID and IP bindings can be reset via the dashboard API, subject to the license's reset budget:
POST /v1/dashboard/licenses/:id/reset-hwid
POST /v1/dashboard/licenses/:id/reset-ip
Reset budgets control:
- max — total number of resets allowed (0 = no resets)
- cooldownHours — minimum time between resets
Sessions
Sessions track active concurrent usage of a license. They're created when a sessionId is passed during license authorization and are used to enforce concurrency limits.
How Sessions Work
- Your application generates a unique
sessionId(e.g., a UUID per app launch) - On each authorization request, pass the
sessionId - GeckoGuard creates or updates the session record
- If concurrency limits are enabled, the number of active sessions is checked
- Sessions that haven't been seen recently can be considered stale
Managing Sessions
List Sessions
const response = await fetch('/v1/dashboard/licenses/LICENSE_ID/sessions', {
headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
});
const { data } = await response.json();
// data.sessions = [{ id, sessionIdHash, ipHash, hwidHash, createdAt, lastSeenAt, revokedAt }]
// data.activeCount = 2
// data.revokedCount = 1
Kill a Specific Session
POST /v1/dashboard/licenses/:id/sessions/:sessionId/revoke
Useful when a user reports a lost/stolen device or wants to log out from a specific location.
Kill All Sessions
POST /v1/dashboard/licenses/:id/sessions/revoke-all
Immediately revokes all active sessions. The user will need to re-authorize on their next launch.
Session Fields
| Field | Description |
|---|---|
sessionIdHash | Hashed session identifier |
ipHash | Hashed IP of the session |
hwidHash | Hashed HWID of the session |
createdAt | When the session started |
lastSeenAt | Last authorization with this session |
revokedAt | When the session was killed (null if active) |
Concurrency Limiting
Set limits.concurrency.mode: 'limit' in your policy with a maxActive count:
{
"limits": {
"concurrency": {
"mode": "limit",
"maxActive": 2
}
}
}
When the limit is reached, new sessions are denied with CONCURRENCY_LIMIT_EXCEEDED. The authorization response includes remaining counts:
{
"limits": {
"remaining": {
"concurrency": 0
}
}
}
Best Practices
- Generate unique session IDs — use a UUID per application launch, not per request
- Reuse the same session ID — send the same ID on periodic re-validations
- Kill sessions on app exit — if your app has a clean exit path, revoke the session
- Monitor session counts — check the dashboard for users with unusually high session counts
- Set reasonable limits — most software works well with 1-3 concurrent sessions