Licenses

Licenses are the core unit of access control in GeckoGuard. Each license grants access to a specific product for a specific end user.

License Lifecycle

1. Creation

Licenses are created through the dashboard or API:

const response = await fetch('https://api.geckoguard.com/v1/dashboard/orgs/ORG_ID/licenses', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_SESSION_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    productId: 'product-id',
    // key: 'CUSTOM-KEY-123',          // Optional — auto-generated if omitted
    // expiresAt: '2025-12-31T23:59:59Z',  // Fixed expiry
    // expiresAfterDays: 30,               // Relative expiry (days after activation)
    // expirationMode: 'never',            // 'never' | 'fixed' | 'afterActivation' | 'both'
    // policyOverride: { ... },            // Override product default policy
    // count: 1                            // Bulk create up to 500 at once
  })
});

2. Activation

When an end user first validates a license that has expiresAfterDays set, the license is automatically activated — the activatedAt timestamp is recorded and the expiry countdown begins.

const response = await fetch('https://api.geckoguard.com/v1/licenses/authorize', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    productId: 'product-id',
    licenseKey: 'LICENSE-KEY-123',
    hwid: 'device-hwid',         // Optional
    ip: '192.168.1.1',           // Optional
    deviceId: 'device-uuid',     // Optional
    sessionId: 'session-uuid',   // Optional: for concurrency limits
    dryRun: false                // Optional: test validation without persisting changes
  })
});

3. Usage

After activation, licenses are validated on each application launch or periodically. Each validation checks:

  • Blacklists — HWID and IP checked against product blacklist
  • Hardware binding — HWID checked against policy (sticky/limit mode)
  • IP restrictions — IP checked against policy, including region-based limiting
  • Concurrency limits — Active session count checked
  • Expiration — Both fixed and relative expiry validated

4. Expiration, Revocation, or Freeze

Licenses can end in several ways:

  • Expire naturally based on their expiration settings
  • Revoked manually by an admin
  • Frozen temporarily to pause expiration countdown

License States

StatusDescription
ACTIVEValid and can be authorized
EXPIREDPast expiration date — automatically set on failed validation
REVOKEDManually disabled by admin
FROZENTemporarily paused — expiration countdown is stopped

License Keys

License keys are unique identifiers. They can be:

  • Auto-generated: GeckoGuard creates a secure random key
  • Custom: You provide your own key format (must be unique per product)

Dry Run Mode

Pass dryRun: true to the authorize endpoint to test validation without persisting any changes (no bindings created, no sessions tracked, no activation recorded). Useful for testing policies:

const result = await authorize({
  productId: 'product-id',
  licenseKey: 'KEY-123',
  hwid: 'test-hwid',
  dryRun: true
});
// result includes debug info about policy evaluation

Policy Overrides

Products have a default license policy, but you can override it per-license:

{
  policyOverride: {
    v: 1,
    limits: {
      hwid: { mode: 'sticky' },
      ip: { mode: 'limit', maxDistinct: 3, windowDays: 30 },
      concurrency: { mode: 'limit', maxActive: 2 },
      resetBudget: {
        hwid: { max: 3, cooldownHours: 24 },
        ip: { max: 5, cooldownHours: 12 }
      }
    }
  }
}

The override is deep-merged with the product default — you only need to specify the fields you want to change.

License Limits

Hardware Binding (HWID)

ModeBehavior
unlimitedNo restrictions on hardware IDs
stickyFirst device is permanently bound
limitAllow up to maxDistinct distinct devices

IP Restrictions

ModeBehavior
unlimitedNo restrictions
stickyFirst IP is permanently bound
limitAllow up to maxDistinct distinct IPs within windowDays

IP limits also support a limitType field:

  • 'ip' (default) — limit by distinct IP addresses
  • 'region' — limit by geographic region (country code via IP geolocation)

Concurrency

ModeBehavior
unlimitedNo session limits
limitMaximum maxActive concurrent sessions

Reset Budgets

Reset budgets control how many times HWID or IP bindings can be reset:

  • max: Total number of resets allowed (0 = no resets permitted)
  • cooldownHours: Minimum hours between resets

Reset endpoints:

  • POST /v1/dashboard/licenses/:id/reset-hwid
  • POST /v1/dashboard/licenses/:id/reset-ip

Freezing Licenses

Freeze a license to temporarily pause its expiration countdown:

// Freeze via PATCH
await fetch('/v1/dashboard/licenses/LICENSE_ID', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer YOUR_SESSION_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ frozen: true })
});

Frozen licenses:

  • Stop counting down toward expiration
  • Can still be validated (authorization succeeds)
  • Track frozenDaysRemaining for restoring time when unfrozen
  • Can be bulk frozen/unfrozen via the org-level endpoints

Bulk Operations

GeckoGuard supports bulk operations on licenses via org-scoped endpoints:

  • Freeze/UnfreezePOST /v1/dashboard/orgs/:orgId/licenses/freeze
  • Revoke/UnrevokePOST /v1/dashboard/orgs/:orgId/licenses/revoke
  • ExtendPOST /v1/dashboard/orgs/:orgId/licenses/extend
  • DeleteDELETE /v1/dashboard/orgs/:orgId/licenses
  • ImportPOST /v1/dashboard/orgs/:orgId/licenses/import
  • ExportGET /v1/dashboard/orgs/:orgId/licenses/export?format=csv|json

Best Practices

  1. Use auto-generated keys — more secure than predictable patterns
  2. Set expiration dates — even if far in the future, it's good practice
  3. Use dryRun for testing — validate your policy setup without side effects
  4. Monitor analytics — check the Analytics dashboard for unusual patterns
  5. Revoke compromised licenses immediately — act quickly if a key is leaked
  6. Use policy overrides sparingly — prefer product-level defaults for consistency
  7. Set up blacklists — proactively block known bad HWIDs or IPs