Machine fingerprint
The SDK computes the fingerprint it sends with each validation, and checks in each token. Each fingerprint LicenseManager hasn’t seen on a license is a new machine, which takes one of its places.
await license.getFingerprint();
// "q3M0bVZ0…Hk=:Xk9fT2pB…w=:x7Kp2QaZ"What it’s made of
Three parts, joined with ::
| Part | What it is | Ties the fingerprint to |
|---|---|---|
| Machine | The SHA-256 of the system’s machine id, in base64. | The computer. |
| Install id | 32 random bytes, in base64, generated the first time and stored in the keychain. | This installation. |
| Product id | Your productId. | Your product. |
- The machine part makes the fingerprint stable, and different on each computer. It’s hashed, so the raw id is never sent.
- The install id makes it hard to fake: copying the machine id of another computer isn’t enough, the secret stored on it is needed too. Copying your app’s files to another computer doesn’t copy it.
- The product id makes the fingerprint different for each of your products on the same computer.
The fingerprint is computed the first time it’s needed, then kept in memory for the life of the LicenseManager. It’s about 100 characters long, within LicenseManager’s limit of 255.
The machine id
macOS
The hardware UUID, IOPlatformUUID, read with ioreg -rd1 -c IOPlatformExpertDevice. It stays the same when macOS is reinstalled.
The value is lower-cased, and spaces are removed. The command has 5 seconds to answer.
When it can’t be read, the SDK falls back on the MAC address of the first network interface that isn’t internal, then on the hostname. Both are less stable: a MAC address can change with a new network adapter or a dock, and a hostname when the computer is renamed. Reading the machine id never throws.
Reinstalls and updates
| Event | Same fingerprint? |
|---|---|
| Restarting the app or the computer | Yes. |
| Updating your app | Yes. |
| Updating the system | Yes. |
| Uninstalling and reinstalling your app | Yes: the install id is stored outside your app’s folder, and survives it. |
| Reinstalling macOS, with the Keychain restored | Yes. |
| Reinstalling Windows or Linux | No: the machine id changes. |
| Deleting the stored data | No: a new install id is generated. |
| Moving to a new computer | No. |
| Another user account on the same computer | On macOS and Linux, no: the stored data is per user, so each user gets their own install id. On Windows, usually yes: one copy of the stored data is in ProgramData, shared by every user. See stored data. |
A new fingerprint is a new machine. The old one keeps its place until it’s deactivated, by you, or by the customer from the customer portal.

Overriding the machine id
Pass fingerprint to choose the machine part yourself, like to license per user instead of per computer. It replaces the machine id only: the result is still hashed, and combined with the install id and product id.
// A fixed value:
new LicenseManager({ productId, publicKey, fingerprint: currentUser.id });
// A function, sync or async:
new LicenseManager({
productId,
publicKey,
fingerprint: async () => (await readMyDeviceId()) ?? "",
});- A function is called the first time the fingerprint is needed, and its result is kept for the life of the
LicenseManager. When it throws, nothing is kept: it’s called again at the next validation. - When it throws during
setLicenseKey(), the error is thrown as is. During background validations, it’s handled like a network error: the SDK falls back on the stored token, which can’t be verified without the fingerprint either, so the state becomesOFFLINE_EXPIRED. - An empty string is accepted: every computer then has the same machine part, and only the install id tells them apart.
See choosing what a machine is for what to use.
Don’t change the fingerprint once you’ve shipped, by adding, removing or changing the fingerprint option. Every computer becomes a new machine at its next validation, and licenses with a max machines start refusing them with machine_limit_reached, until the old machines are deactivated. Their stored tokens stop working offline too.
Edge cases
Cloned virtual machines share the same machine id. A clone of a virtual machine where your app was already activated also copies the stored install id: both have the same fingerprint, and share one place. Clones made before the first launch of your app each generate their own install id.
Docker and CI, where the machine id file is often missing or shared: the SDK falls back on the MAC address or the hostname, which can change on each run. Pass fingerprint in those environments.
The keychain can’t be written and the file fallback fails too, like on a read-only home folder. The install id can’t be stored: a new one is generated on each launch, and each launch is a new machine. It’s very unlikely on a customer’s computer.
Two products on the same computer have two different fingerprints, and are two machines, one in each license.