Mission Shrestha

Personal project

Licensing system

A signing server and an offline client that verifies licenses without calling home, built after teaching myself the cryptography.

Enlarge: The offline client's License Console, which runs with no network: the license status reads Valid, for ACME Corp on the Enterprise edition, a perpetual license valid from 2025-01-01 to 2099-12-31, beside a panel to upload or replace a signed license as JSON, with the feature gating demo below.
Dates
September 2025 – November 2025
Role
Design and implementation
Stack
  • Python
  • Django REST Framework
  • Ed25519
  • React
Links

Screenshots

  • Enlarge: Uploading a license in the offline client: the signed license JSON is pasted in, marked as valid JSON and accepted, while the status on the left now reads Expired, for a subscription that ended on 2025-12-31, and each gated feature shows Not available.
    An expired license: the signature checks out, and the gated features stay off.
  • Enlarge: A parsed license: meta with version 1, the Ed25519 algorithm and key ID main-v1; a payload with the issuer, edition, product, customer, features, validity dates, deployment, license ID, type and usage limits; and the signature.
    A signed license: the payload and its Ed25519 signature.

Context

DataFuseAI ships to customers’ own servers. A license has to work on a machine that may never reach the internet, can’t be forged by editing a file, and has to be revocable when a contract ends. I didn’t know cryptography when the requirement arrived. These two public repositories are the companion to the work: the same design, built independently to learn and to show it.

My role

All of it: the study, the design, the server, the client, and the docs. The learning repo, cryptography-in-python-fundamentals, is the trail of how I got there.

Constraints

Offline verification. No shared secret on the client (anything on the customer’s box is readable). Tamper detection that fails closed. Revocation without a phone-home. An audit trail for who issued what, when.

What I built

Enlarge: Code-drawn diagram: a signing server issues a license; an offline client verifies it with a public key
How the licensing system fits together: sign on the server, verify offline.
  • Key generation on the server: an Ed25519 keypair; the private key never leaves the server.
  • Signing. A license is a small signed document — customer, scope, expiry, feature flags — with the signature attached.
  • Offline verification on the client: the public key ships with the client; verification is a signature check, no network.
  • Tamper detection. Any edit to the license body breaks the signature; the client fails closed.
  • Revocation via short-lived licenses and a revocation list the client applies when it does reach the server.
  • Audit trail. Every issue, renewal, and revocation logged with actor and timestamp.
  • Server in Django REST Framework; client in DRF + React.

Decisions and why

  • Ed25519 over RSA: smaller keys, fast verification, fewer ways to misuse it.
  • Signed documents over encrypted ones: the license isn’t secret; its integrity is what matters, and a public key on the client is safe.
  • Short expiry plus a revocation list instead of always-online checks, so an offline customer keeps working and a cancelled one stops within the window.

Outcome

A working reference implementation, Apache-2.0, that a reader can run end to end. At work, the production system built on the same design shipped with the product.

What I’d change

Add key rotation from day one; retrofitting it means every client needs a new public key, which is exactly the offline problem again.

The server, poc-license-server, the client, poc-offline-client, and the learning repo, cryptography-in-python-fundamentals, are linked at the top of this page.

Hiring for work like this?

Get in touch about a roleBook a 20-minute call