Device binding ties a license key to a fixed number of machines using a stable hardware identifier (HWID), so a single key cannot be shared across unlimited computers. When a device validates, its HWID is registered against the key; once the key reaches its device limit, new machines are rejected. This is the most effective way to stop one paying customer from quietly running your software on a hundred machines.
This guide shows how to add HWID binding to a Python application the right way, including the mistake that breaks it on mobile.
What is an HWID and why device binding matters
An HWID is a string that identifies a machine. License device binding stores the HWIDs that have activated a key and enforces a maximum. Without it, a leaked key works everywhere. With it, a key is only valid on the devices you allow, and you can raise the limit or reset devices per customer.
Step 1: Install the SDK
pip install pylicensify
Step 2: Set a device limit on the key
In the Licers dashboard, open your product, create or edit a license key, and set its device limit (max devices). A limit of 1 locks the key to a single machine; 3 allows a laptop, desktop, and a spare.
Step 3: Validate — the SDK handles the HWID for you
from pylicensify import LicenseClient
client = LicenseClient(public_key="YOUR_PUBLIC_KEY")
result = client.validate("PY-XXXXXXXXXXXXXXXX")
if result:
unlock_app()
else:
print("Not licensed on this device:", result.error)
On first run the device registers against the key. On later runs the same device is recognized. When a new device pushes the key past its limit, validation returns an error instead of a signed success.
The mistake that breaks device binding on mobile
A naive HWID uses the network cards MAC address. On desktops that is stable, but on Android, many virtual machines, and containers the MAC cannot be read, so the value is random on every run — every launch looks like a brand new device and the key hits its limit almost immediately.
A correct HWID is stable across runs on every platform. The Licers SDK does this for you: it uses the MAC when it is genuinely readable, and otherwise falls back to a random id persisted to disk and reused on every run. If you supply your own HWID, make sure it is stable across restarts:
# Only override if you have a stable, per-install fingerprint of your own.
client.validate("PY-XXXX...", hwid=my_stable_fingerprint())
Step 4: Reset devices for a customer
When a customer replaces a laptop, remove old devices from the key in the dashboard so the new machine can activate. This keeps the limit meaningful without punishing legitimate upgrades.
Frequently asked questions
What happens when a key reaches its device limit?
New devices are rejected with an error while already-registered devices keep working. Raise the limit or remove an old device to free a slot.
Does HWID binding work offline?
Yes. Offline license files can include a device lock that is verified locally against the machine, with no network call.
Can a user fake their HWID?
They can change what your app sends, which is why the response is cryptographically signed and why hardening the client matters. Device binding raises the cost of sharing; signed validation stops fake-server attacks.
Ready to lock your keys to devices? Create a free account and read the integration guide.