# POS licensing and device binding

For a POS that cannot be quietly copied, the **licence issuer must be outside the POS application**. A check that is only inside this code or `shop.db` can be removed by a person who has the program files.

## Recommended flow

1. On first run the POS creates a device ID from a Windows machine identifier plus an installation ID. It starts a **7-day trial** and stores the first-run time in both the database and a signed local file.
2. The activation page shows the device ID and an activation request code.
3. Only the owner opens a small **licence portal** (or a protected admin web page), enters that device ID and the plan/end date, and creates a signed activation token.
4. The customer enters the token in POS. The app verifies it with the embedded public key and binds it to that one device ID.
5. At startup and before a sale, the POS checks: signature, device ID, expiry date, and revocation status. If trial has ended or the licence is invalid, it shows the activation page and does not open POS or create invoices.
6. The app checks the portal once every 7 days. Allow a small offline grace period (for example 3 days); after that it requires an internet check. The portal can revoke a stolen or refunded licence.

## Important security rules

- Keep the signing **private key only on your licence portal**, never in this POS project or the installed software.
- POS contains only the matching public key, so it can verify but cannot create a valid licence.
- Store a signed licence copy in `%ProgramData%` and in the database; use both to make simple date-reset attempts visible.
- Use an installer and package the app as an executable. Python source and the SQLite database must not be the deployed product.
- Device binding discourages sharing; no offline desktop app can guarantee 100% copy protection against a determined technical attacker. Portal verification and code signing make bypassing materially harder.

## Do you need a separate software?

Not a separate POS for every customer. You need one small owner-only licence service/portal (it can be a simple Flask/Django web app) and one endpoint for activation, validation, and revocation. The customer POS stays the same application.
