Files
IT_Ticket_System/LICENSING_GUIDE.md
T
2026-05-22 16:31:19 -04:00

12 KiB
Raw Blame History

TechDesk Licensing — Vendor Operations Guide

This document covers everything you need to do as the vendor: setting up the license server, generating keys, publishing the app to customers, and issuing keys. Read it top to bottom the first time, then jump to the relevant section for ongoing operations.


Table of Contents

  1. One-Time Setup (Do This First)
  2. Deploy the License Server
  3. Publish TechDesk to a Customer
  4. Issue a Key — Current Customer (First Time)
  5. Customer Applies the Key
  6. Renew an Expiring Key
  7. Ongoing Operations Checklist

1. One-Time Setup (Do This First)

This section is done once, ever. It generates the RSA key pair that secures all license keys. Do it on a machine you control — your development machine or the server where the license server will run.

Step 1.1 — Install dependencies

cd license_server
pip install -r requirements.txt

Step 1.2 — Generate the RSA key pair

python generate_keys.py

Output:

Key pair generated successfully.
  Private key : private_key.pem  (KEEP SECRET)
  Public key  : public_key.pem   (safe to embed in TechDesk)

Two files are created:

File What it is Who sees it
private_key.pem Signs all license keys You only. Never leave this machine.
public_key.pem Verifies license keys Embedded in TechDesk. Customers have it.

Critical: private_key.pem must NEVER be committed to git, sent to customers, or included in any build. If it leaks, anyone can forge unlimited valid license keys. Back it up securely (encrypted drive, password manager).

Step 1.3 — Embed the public key in TechDesk

Open app/services/license_service.py and find the PUBLIC_KEY_PEM constant near the top. Replace the placeholder with the full contents of public_key.pem:

PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
(your actual key here)
...
-----END PUBLIC KEY-----"""

Include the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- lines.

After this change, TechDesk will validate license keys against your real public key. Before this step, all keys fail and the app runs in Community mode.

Step 1.4 — Commit the public key change

git add app/services/license_service.py
git commit -m "Embed RSA public key for license validation"

This is the only license-related change that goes into the customer-facing codebase. private_key.pem stays off git permanently — add it to .gitignore:

echo "license_server/private_key.pem" >> .gitignore
echo "license_server/licenses.db" >> .gitignore
git add .gitignore
git commit -m "Ignore license server secrets from git"

2. Deploy the License Server

The license server is a small Flask app that runs on your machine or a private server. It does not need to be reachable from the internet — you only access it when generating new keys.

Option A — Run locally on your development machine (simplest)

Good for low volume (fewer than 50 customers). Run it only when you need to generate a key, not 24/7.

cd license_server

# Set a strong admin password (or set the env var in your shell profile)
export LICENSE_SERVER_PASSWORD="your-strong-password-here"

python app.py

Open http://127.0.0.1:5001 in your browser. Log in with the password you set.

If you prefer a persistent server so you can generate keys from anywhere:

  1. Copy the license_server/ directory to your VPS (via scp or git)
  2. Copy private_key.pem to the VPS via a secure channel (not email)
  3. Set environment variables:
export LICENSE_SERVER_PASSWORD="your-strong-password-here"
export SECRET_KEY="random-64-char-string-here"
  1. Run with gunicorn behind nginx (or just run directly if access is restricted to your IP via firewall):
pip install -r requirements.txt
python app.py
  1. Restrict access to your IP in the VPS firewall — port 5001 should never be publicly reachable.

Important: The license server has no multi-user auth, no HTTPS, and no rate limiting. It is designed for internal use only. Never expose port 5001 to the internet.


3. Publish TechDesk to a Customer

When you deliver TechDesk to a new customer, you give them the codebase. Here is exactly what to include and exclude.

What to include

Everything in the project except the items listed below.

What to EXCLUDE

Path Why
license_server/private_key.pem Signing key — leaking it lets anyone forge keys
license_server/licenses.db Your customer database — not their business
license_server/ (entire folder) Customers don't need the server
.env Contains your secrets, not theirs
logs/ Your logs
app/static/uploads/ Your data
migrations/ (optional) Only needed if they'll run migrations manually

Option A: Git archive (cleanest)

# From your project root — produces a zip with no git history and no excluded files
git archive --format=zip --output=techdesk-v1.0.zip HEAD

Then manually remove license_server/ from the zip if it's tracked in git:

zip -d techdesk-v1.0.zip "license_server/*"

Option B: Manual zip

# Exclude everything sensitive
zip -r techdesk-v1.0.zip . \
  --exclude "*.git*" \
  --exclude "*.env*" \
  --exclude "license_server/*" \
  --exclude "logs/*" \
  --exclude "app/static/uploads/*"

Checklist before sending:

  • app/services/license_service.py contains the real public key (not the placeholder)
  • license_server/ is not in the archive
  • No .env file in the archive
  • No private_key.pem anywhere in the archive

4. Issue a Key — Current Customer (First Time)

Your existing customer is running TechDesk without a license key right now (Community mode). Here is how to issue them a key.

Step 4.1 — Start the license server

cd license_server
export LICENSE_SERVER_PASSWORD="your-password"
python app.py

Open http://127.0.0.1:5001 and log in.

Step 4.2 — Fill in the Generate form

Field What to enter
Customer / Company Name Their company name (e.g. LT Services Inc)
Contact Email Their admin's email address
Tier Business (recommended starting tier)
Duration 1 year (365 days) — gives you an annual renewal cycle

Click Generate Key.

Step 4.3 — Copy the key

The full key appears on screen immediately after generation, like:

TDESK-eyJjdXN0b21lciI6Ikx....(long string)....

Copy the entire key — it is shown in full only once on screen. The database stores only a short preview for your records. If you lose it, generate a new one.

Step 4.4 — Send the key to the customer

Send the key via email, Slack, or your preferred channel. Include:

  • The full TDESK-... key string
  • The expiry date (1 year from today)
  • A link to the setup instructions below (or paste them directly)

Example email:

Subject: Your TechDesk License Key

Hi [Name],

Your TechDesk Business license key is below. It is valid until [expiry date].

TDESK-eyJjdXN0b21lciI6...

To activate:

  1. Open your .env file on the TechDesk server
  2. Add this line: LICENSE_KEY=TDESK-eyJ... (the full key)
  3. Restart TechDesk: sudo systemctl restart gunicorn
  4. Visit Admin → License to confirm activation

Let me know if you have any questions.

Step 4.5 — Verify the key was recorded

Back in the license server UI, confirm the new row appears in the Issued Licenses table with the correct customer name, tier, and expiry date. This is your audit trail.


5. Customer Applies the Key

Share these instructions with the customer. They only need to do this once (and again on renewal).

Customer instructions

On the TechDesk server:

  1. Open the .env file in the TechDesk installation directory:

    nano /home/it-ticket/myapp/.env
    
  2. Add or update this line (paste the full key you received):

    LICENSE_KEY=TDESK-eyJjdXN0b21lciI6...
    
  3. Save the file and restart TechDesk:

    sudo systemctl restart gunicorn
    
  4. Verify activation — log in to TechDesk as admin and go to Admin → License. The page should show:

    • A Business (or Enterprise) tier badge
    • Your company name and email
    • The expiry date
    • Green checkmarks on all licensed features
  5. The warning banner at the top of the page (if it was showing) will disappear.

If something goes wrong:

Symptom Likely cause Fix
Banner still shows "No license key" .env not saved or service not restarted Re-check .env, restart gunicorn
Banner shows "License key invalid" Key was truncated or modified during copy Re-copy the full key, ensure no line breaks
License page shows "Public key not configured" The public key placeholder was not replaced Contact vendor — the app build is missing the public key

6. Renew an Expiring Key

30 days before expiry the customer will see a blue banner: "Your license expires in X days." When expiry passes, it turns to a yellow warning and features lock down to Community tier.

Renewal process

  1. Start the license server (same as Step 4.1)
  2. Generate a new key for the customer (same as Step 4.24.3)
    • Use the same customer name, email, and tier
    • Choose the same duration (1 year)
  3. Send the new key to the customer (same as Step 4.4)
  4. Customer replaces the old LICENSE_KEY= line in .env with the new key and restarts — same as Step 5

The old key and new key are independent — the customer simply overwrites the .env value. There is no overlap or grace period to manage on your end.


7. Ongoing Operations Checklist

When you generate a new version of TechDesk

  • Ensure app/services/license_service.py still contains the real PUBLIC_KEY_PEM (it should, unless you accidentally reverted it)
  • Exclude license_server/ and .env from the customer build
  • Test: start the app with no LICENSE_KEY → confirm Community mode banner appears
  • Test: start the app with a valid key → confirm correct tier and features

When a customer reports a licensing issue

  1. Ask them to go to Admin → License and send you a screenshot
  2. Check the reason shown:
    • no_key → they haven't added the .env line or haven't restarted
    • expired → they need a renewal key
    • invalid_signature → the key was corrupted in transit; re-send it
    • no_public_key → their build is missing the public key; send a fixed build

If private_key.pem is ever compromised

All previously issued keys remain valid (you cannot invalidate them — offline model has no revocation). Your only recourse:

  1. Generate a new RSA key pair (python generate_keys.py after deleting the old files)
  2. Embed the new public_key.pem in TechDesk
  3. Re-issue keys to all existing customers
  4. Send them the updated build with the new public key

This is the main limitation of offline keys — treat private_key.pem with the same care as a master password.

Backing up private_key.pem

Store at least two encrypted copies:

  • A password manager (Bitwarden, 1Password, etc.) as a secure note
  • An encrypted USB drive stored offline

If you lose private_key.pem you cannot issue new keys and cannot recover existing ones — you would need to do a full key rotation (same as the compromise scenario above).


Last updated: 2026-05-22