Konvoa Engineering
What desktop license validation must keep server-side
A practical boundary for deciding what a desktop client may prove and what only your service should authorize.
The binary is a participant, not an authority
A desktop application runs on hardware its vendor does not control. The person operating that machine can inspect memory, patch branches, intercept local storage, replay network traffic, or replace an entire function. Obfuscation may raise the effort required, but it does not turn a customer-controlled process into a trustworthy policy engine.
That leads to a useful design rule: let the client prove facts that require possession of a local secret, but let the service decide whether those facts currently authorize an action. A device can prove that it holds a private key. It cannot make the final decision that an account is paid, a license has not been revoked, or a subscription includes a protected release.
Keep commercial state on the service
The server-side record should contain the current account state, license term, subscription assignments, device binding, session families, and revocation state. Those records are the inputs to one authorization decision. When an operator bans an account or revokes a license, every later protected request should observe that change without waiting for a new binary.
Avoid representing lifetime business state as one boolean stored beside the executable. Even a correctly signed local license file becomes stale after a refund, chargeback, support intervention, or policy change unless the application regularly obtains a fresh server decision.
- Account status and application ownership
- License issue, expiry, extension, and revocation state
- Subscription tiers attached to the entitlement
- Device-key binding and legitimate rebind history
- Active access sessions, refresh families, and pending download tickets
Let the client hold a device key
A device key is different from commercial state. The private half can remain on the customer’s machine while the public half is enrolled with the service. Each protected request includes a timestamp, a fresh nonce, a hash of the exact body, and a signature made by that private key. The server verifies possession before it evaluates the license.
This limits what a stolen bearer value can do. A copied access token alone is insufficient when the request must also be signed by the enrolled device key. The design still assumes the machine may be compromised, but it makes the protocol explicit about which key authorized each request.
Sign the response as carefully as the request
The client also needs a reliable way to distinguish the vendor’s decision from a forged local response. Pin the service’s public response key in the application and verify a signature over the response status, request identifier, timestamp, and exact response-body hash before parsing protected fields.
Verification order matters. If a response is encrypted, hash and sign the encrypted envelope that actually travels over the network, verify that signature first, and only then decrypt. Re-serializing parsed JSON and verifying a newly generated representation risks accepting different bytes from the ones the server signed.
Make offline access a bounded exception
Some products genuinely need an offline window. Treat it as a time-bounded, signed lease issued by the service, not a permanent copy of server state. The lease should name the application, subject, device key, permitted scope, issue time, and hard expiry. Keep the window short enough that a revocation delay matches the business risk.
A client clock is not trustworthy enough to grant an unlimited extension. Record the last accepted server time, reject implausible rollback, and require an online refresh before the lease expires. Be honest in product language: offline tolerance means revocation is eventually consistent during that window.
Review the complete decision, not one check
Production authorization is a conjunction. The signature can be valid while the account is banned. The license can be current while the device binding is wrong. The account can be active while the subscription does not permit a requested file. Return success only after the request proof, replay state, identity, entitlement, device, scope, and session all pass together.
This boundary keeps the desktop integration small and makes operations reversible. The client proves possession and verifies the service response. The service owns the answer.