05/22 Update gitignore

This commit is contained in:
2026-05-22 16:58:41 -04:00
parent fe89ab96bb
commit b115571065
2 changed files with 2 additions and 387 deletions
+1
View File
@@ -52,3 +52,4 @@ Thumbs.db
.coverage .coverage
htmlcov/ htmlcov/
license_server/ license_server/
LICENSING_GUIDE.md
-386
View File
@@ -1,386 +0,0 @@
# 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)](#1-one-time-setup-do-this-first)
2. [Deploy the License Server](#2-deploy-the-license-server)
3. [Publish TechDesk to a Customer](#3-publish-techdesk-to-a-customer)
4. [Issue a Key — Current Customer (First Time)](#4-issue-a-key--current-customer-first-time)
5. [Customer Applies the Key](#5-customer-applies-the-key)
6. [Renew an Expiring Key](#6-renew-an-expiring-key)
7. [Ongoing Operations Checklist](#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
```bash
cd license_server
pip install -r requirements.txt
```
### Step 1.2 — Generate the RSA key pair
```bash
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`:
```python
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
```bash
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`:
```bash
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.
```bash
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.
### Option B — Run on a private VPS (recommended for production)
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:
```bash
export LICENSE_SERVER_PASSWORD="your-strong-password-here"
export SECRET_KEY="random-64-char-string-here"
```
4. Run with gunicorn behind nginx (or just run directly if access is restricted
to your IP via firewall):
```bash
pip install -r requirements.txt
python app.py
```
5. 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 |
### Recommended delivery method
**Option A: Git archive (cleanest)**
```bash
# 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:
```bash
zip -d techdesk-v1.0.zip "license_server/*"
```
**Option B: Manual zip**
```bash
# 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
```bash
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:
```bash
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:
```bash
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*