# LicenseVault Self-hosted license management server with web UI. Built with Go + HTMX + SQLite. Runs on Proxmox via Docker. ## Stack - **Go** — HTTP server (chi router) - **HTMX** — reactive UI without a JS framework - **SQLite** — zero-config database - **Caddy** — automatic HTTPS ## Deploy on Proxmox ### 1. Point your domain Create an A record: `licenses.yourdomain.com → your-proxmox-vm-ip` ### 2. Edit Caddyfile ``` licenses.yourdomain.com { reverse_proxy app:8080 } ``` ### 3. Deploy ```bash git clone cd licenseServer docker compose up -d ``` ### 4. First-time setup Open `https://licenses.yourdomain.com/setup` and create your admin account. --- ## REST API (for client apps) ### Validate a license ``` POST /api/v1/validate Content-Type: application/json { "license_key": "XXXX-XXXX-XXXX-XXXX", "machine_id": "sha256-hardware-fingerprint", "hostname": "customer-pc", "os": "windows" } ``` Response: ```json { "valid": true, "type": "expiry" } { "valid": false, "message": "license expired" } ``` ### Go client example ```go import ( "bytes" "encoding/json" "net/http" "github.com/example/license/hwid" ) fp, _ := hwid.Collect() body, _ := json.Marshal(map[string]string{ "license_key": licenseKey, "machine_id": fp.Hash(), "hostname": fp.Hostname, "os": fp.OS, }) resp, _ := http.Post( "https://licenses.yourdomain.com/api/v1/validate", "application/json", bytes.NewReader(body), ) var result struct { Valid bool `json:"valid"` Message string `json:"message"` } json.NewDecoder(resp.Body).Decode(&result) if !result.Valid { log.Fatalf("License invalid: %s", result.Message) } ``` ## Environment Variables | Variable | Default | Description | |-----------|------------------|------------------------| | PORT | 8080 | HTTP port | | DB_PATH | ./licenses.db | SQLite database path | ## License Types **Expiry** — valid until a date. Machine binding optional. **Usage** — valid for N activations. Each `/api/v1/validate` call counts as one use. Machine ID is the SHA-256 hardware fingerprint from the `hwid` package. Leave blank when issuing to allow any machine (floating license).