How do you enforce a usage quota for on-prem software when the customer can clone or snapshot the VM (air-gapped)?
We sell an on-prem B2B product (Java/Spring Boot + PostgreSQL) that runs on a VM in the customer's own data centre. The site is air-gapped, so no license server, heartbeat or phone-home is possible. The customer's IT has full admin over the hypervisor and root in the guest.
The contract limits usage to N completed transactions per year. Today we enforce it with:
- a license file signed with our private key (the app only holds the public key);
- an append-only, hash-chained usage ledger in the database;
- periodic usage reports the customer sends us, which we verify offline.
The problem: cloning the VM, or reverting it to a snapshot, copies the license, the ledger and the counters together and consistently. Every copy passes every local check. Two clones get 2× the quota, and a snapshot revert resets the count.
What we found so far:
- VM Generation ID is the only signal built for this, but a non-root process on a Linux guest can't read it, and the hypervisor admin can pin or disable it.
- UUID, MAC, machine-id and vTPM are copied with the VM or easy to forge.
- TPM or SGX counters on the server aren't reachable from a VM.
Questions for anyone who has shipped on-prem, usage-based licensing:
What actually works for you in air-gapped VMs? USB dongles with on-chip counters (Wibu CodeMeter, Thales Sentinel), FIDO2 keys, a physical appliance, or something else?
If you use a dongle in a VM, how do you handle ESXi/Hyper-V passthrough, vMotion/HA and dongle failure?
Has anyone used a FIDO2 key's signature counter as a usage meter?
Or did you give up on technical enforcement and rely on audits?
Not looking to stop determined attackers, just to make cheating detectable or impractical.