feat(licenses): heartbeat mode — validate license key on first registration with domain matching #363

Closed
opened 2026-05-31 16:26:21 +00:00 by jmiller · 1 comment
Owner

Summary

Add a "heartbeat mode" option that validates license keys on first registration (initial install/activation) and optionally enforces domain matching on subsequent heartbeats.

Behavior

First Registration

When an extension first contacts the update server with a license key:

  1. Validate the key is active and not expired
  2. If domain matching is enabled, lock the key to the requesting domain
  3. Record the registration event (IP, domain, user-agent, timestamp)
  4. Return success with license metadata (package name, channels, expiry)

Subsequent Heartbeats

On periodic check-ins (update checks, daily heartbeats):

  1. Re-validate the key is still active and not expired
  2. If domain matching is enabled, verify the domain matches the registered one
  3. Update last_heartbeat timestamp
  4. If key has been revoked/expired since registration, return invalid

Domain Matching Option

A per-key or per-package setting:

  • Off: Key works from any domain (current default behavior)
  • Lock on first use: Domain is auto-set on first heartbeat (already implemented)
  • Strict matching: Every heartbeat must come from a registered domain, reject mismatches immediately

Configuration

Add to package or key settings:

  • : none | register_once | periodic (default: periodic)
  • : none | lock_on_first_use | strict (default: lock_on_first_use)

Use Cases

  • Detect pirated/shared keys (same key from multiple domains)
  • Auto-revoke keys that haven't checked in for X days
  • Notify admin when a key is used from an unexpected domain

Claude Opus 4.6 (1M context) noreply@anthropic.com

## Summary Add a "heartbeat mode" option that validates license keys on first registration (initial install/activation) and optionally enforces domain matching on subsequent heartbeats. ## Behavior ### First Registration When an extension first contacts the update server with a license key: 1. Validate the key is active and not expired 2. If domain matching is enabled, lock the key to the requesting domain 3. Record the registration event (IP, domain, user-agent, timestamp) 4. Return success with license metadata (package name, channels, expiry) ### Subsequent Heartbeats On periodic check-ins (update checks, daily heartbeats): 1. Re-validate the key is still active and not expired 2. If domain matching is enabled, verify the domain matches the registered one 3. Update last_heartbeat timestamp 4. If key has been revoked/expired since registration, return invalid ### Domain Matching Option A per-key or per-package setting: - **Off**: Key works from any domain (current default behavior) - **Lock on first use**: Domain is auto-set on first heartbeat (already implemented) - **Strict matching**: Every heartbeat must come from a registered domain, reject mismatches immediately ## Configuration Add to package or key settings: - : none | register_once | periodic (default: periodic) - : none | lock_on_first_use | strict (default: lock_on_first_use) ## Use Cases - Detect pirated/shared keys (same key from multiple domains) - Auto-revoke keys that haven't checked in for X days - Notify admin when a key is used from an unexpected domain --- *Claude Opus 4.6 (1M context) <noreply@anthropic.com>*
Author
Owner

Implemented across multiple commits:

  • FirstUsedUnix field on LicenseKey (set on first TouchHeartbeat)
  • Auto-domain association (lock-on-first-use) in ValidateLicenseKey
  • DomainLockHours grace period on LicensePackage
  • LastHeartbeatUnix tracking on every validation
  • IsDomainKnownForKey for efficient domain lookups
Implemented across multiple commits: - FirstUsedUnix field on LicenseKey (set on first TouchHeartbeat) - Auto-domain association (lock-on-first-use) in ValidateLicenseKey - DomainLockHours grace period on LicensePackage - LastHeartbeatUnix tracking on every validation - IsDomainKnownForKey for efficient domain lookups
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoGitea#363