Modern Control — Licensing
Honest summary: client-distributed Lua cannot be made impossible to copy. Security comes from per-installation credentials and server-side license activation — not from obfuscation.
Architecture
Organization
└── License (status, plan, serverAllowance)
└── LicenseActivation (serverId, installationId, status)
Dashboard/backend is authoritative.
States
| Status | Agent auth |
|--------|------------|
| ACTIVE | Allowed |
| GRACE | Allowed (post-expiry grace window) |
| SUSPENDED | Denied |
| REVOKED | Denied |
| EXPIRED | Denied (unless GRACE) |
Customer data is not deleted on expiry/revoke.
Installation identity
At successful pairing the backend mints installationId (inst_… random).
This is not player HWID and not a brittle hardware fingerprint.
Optional supporting signal: lastHostHint from agent hostname (non-authoritative).
What possession of addon files grants
Nothing operational. Without a valid pairing → permanent secret + ACTIVE license activation, the dashboard rejects the agent.
Copied config
A copied permanent secret can authenticate until rotated/disconnected. Mitigations:
- unique secrets per install
- disconnect / rotate / transfer workflows
- conflict flags when the same
installationIdis seen on multiple ACTIVE activations
IP changes alone do not revoke a license.
Host migration
Owner uses License → Transfer host (or POST /api/licenses/transfer):
- Old credentials invalidated
- Seat retained
- New pairing code issued
- Paste config on new host → pair → online
See docs/CUSTOMER_INSTALL.md for the full step-by-step transfer procedure.
Outages
If Modern Control is unreachable, GMod gameplay continues. Telemetry/commands pause. Temporary unreachability is not treated as piracy.
Operator procedures
Platform SUPERADMIN with x-mdn-operator-access: 1:
GET/POST/PATCH /api/operator/licenses— issue / suspend / revoke / restore
Customers never receive these capabilities.
Cache
License resolution cached ~15s per server (LICENSE_CACHE_TTL_MS). Status changes clear relevant cache entries.
Privacy
Stored: org, license metadata, server id, installation id, optional host hint, activation timestamps.
Not stored: player hardware IDs, invasive machine fingerprints.
Agent version compatibility
The dashboard evaluates each connected agent's version and surfaces one of four labels:
| Label | Meaning |
|-------|---------|
| CURRENT | Agent is on the expected major.minor — no action needed |
| UPDATE AVAILABLE | Agent is 1–2 minor versions behind — update recommended |
| INCOMPATIBLE | Agent is too old — full functionality not guaranteed; update required |
| UNKNOWN | Version could not be determined or agent is ahead of expected |
The compatibility baseline is controlled by EXPECTED_AGENT_VERSION_PREFIX on the dashboard server. Current default: 0.9.