Skip to content

.NET SDK — device fingerprints

Activation binds a seat to a device fingerprint — a stable identifier for the install. The fingerprint is what lets the platform tell “the same machine reconnecting” from “a new machine claiming a seat”, so a restart or redeploy reuses its seat instead of consuming a new one.

Seats are counted per fingerprint. If the fingerprint changes between runs, each run looks like a new device: the entitlement fills up and further activations are refused. A fingerprint that stays constant across process restarts is therefore the single most important property — prefer a value you can guarantee is stable over one derived from volatile hardware.

The SDK resolves it through INodeIdProvider:

  • From configuration — the default provider reads MonetizeIt:LicenseConsumer:NodeId. Set it to a value that is stable for the install (for example, a per-deployment id you persist).
  • Derived from the device — a machine-derived identifier (machine name and network adapter). Convenient, but on machines with VPNs or virtual adapters the “first” adapter can vary between runs, so it is best treated as a fallback rather than the primary identity.

DeviceIdDeviceFingerprint composes a fingerprint from device traits and hashes it on the device — raw values never leave the machine. Pass it to UseNodeId on the fluent builder, or register it as the INodeIdProvider:

var fingerprint = new DeviceIdDeviceFingerprint
{
FingerprintMethod = DeviceIdDeviceFingerprint.FingerprintMethods.MacAddress
| DeviceIdDeviceFingerprint.FingerprintMethods.MachineName
| DeviceIdDeviceFingerprint.FingerprintMethods.OsVersion
};

The default is MacAddress | MachineName. Available traits: MachineName, OsVersion, MacAddress, UserName.

For a value you control — a tenant id, a provisioned device id, a stored GUID — register a scoped INodeIdProvider before AddMonetizeItLicenseConsumer:

builder.Services.AddScoped<INodeIdProvider>(_ =>
StaticNodeId.Create(deploymentId));

In a multi-tenant host, resolve the fingerprint from the current tenant so each tenant’s seats are counted independently — pair this with the per-tenant ILicenseKeyProvider from install and configure.

Beyond the composite hash, the provider also surfaces each trait as its own one-way hash (Components). Sending components lets the server match a device whose fingerprint drifted — a swapped network card, an OS upgrade — under the entitlement’s component-matching strategy (match any, two, or most) instead of burning a new seat. Omitting components keeps strict exact matching. It’s additive: old clients keep working unchanged.

Where hardware traits are meaningless (containers, autoscaling), derive a stable logical fingerprint instead:

using Revenusion.MonetizeIt.Client.AspNetCore.Common;
var fingerprint = LicenseFingerprint.ForTenant(customerIdentifier);

Same identifier, same fingerprint — one seat per customer environment across restarts and instances.