RackVision License Server

...
Total Devices
-
Online
-
Expiring Soon
-
Expired
-
Revoked
-
Devices
Activation Keys
Audit Log
Settings
Docs
IdentifierHostnameStatusVersionIPExpiresLast HeartbeatActions
KeyIdentifierUsed / MaxActiveCreatedNotesActions
TimeActionIdentifierHostnameDetailsIP

Change Password


Server Ed25519 Key

This public key must be embedded in the Rust client binary for license verification.

Loading...

Overview

The RackVision License Server manages activation and licensing for Multiload Updater Rust clients deployed at terminal sites. Each client must activate once with the server, then operates offline for up to 7 days before needing to renew.

How It Works

  • The server holds an Ed25519 private key used to sign license tokens.
  • The Rust client binary has the matching public key embedded at compile time.
  • When a client activates or renews, the server signs a token containing the device ID, machine fingerprint, and a 7-day expiry.
  • The client stores this token locally as license.dat and verifies it offline using the embedded public key — no server contact needed during the 7-day window.
  • A background watchdog checks expiry every 5 minutes. If expired and the server is unreachable, the client shuts down immediately.

Architecture

License Server (this server)
  ├── REST API:  /api/license/activate, /api/license/renew
  ├── WebSocket: /ws/device  (Rust clients — heartbeat + push events)
  └── WebSocket: /ws/admin   (this dashboard — real-time updates)

Rust Client (on-site terminal)
  ├── Embedded Ed25519 public key (compile-time)
  ├── license.dat (local, created on activation)
  ├── WebSocket client → /ws/device (heartbeat every 60s)
  └── Background watchdog (checks expiry every 5 min)

Initial Server Setup

  1. Configure .env with your MSSQL credentials, admin username/password, and JWT secret.
  2. Run npm install then npm run dev (or npm start for production).
  3. The server automatically creates the rack_vision_license database and all tables on first start.
  4. An Ed25519 key pair is auto-generated on first start. You can view the public key in the Settings tab.

Embedding the Public Key in the Rust Client

This step links the server to the client. Without the correct public key, clients cannot verify license tokens.
  1. Option A — Generate script:
    cd rack_vision_license_server
    npm run generate-keys
    cp keys/server_public.key /path/to/multiload_updater_rust/keys/server_public.key
  2. Option B — From database: Go to Settings tab, copy the base64 public key, decode it to 32 bytes, place at keys/server_public.key.
  3. Rebuild the Rust binary:
    cd multiload_updater_rust
    cargo build --release
If you rotate the server key (Settings tab), ALL existing client binaries become invalid. You must rebuild and redeploy every client.

Configuring a New Client

Step 1: Generate an Activation Key

  1. Go to Activation Keys tab → Generate Activation Key.
  2. Optionally set Identifier to lock the key to a specific site.
  3. Copy the generated key (e.g. A3K7-XNPQ-8V2D-FWJT) and send it to the site operator.

Step 2: Configure the Client .env

LICENSE_SERVER_URL="https://license.rackvision.app"
LICENSE_SERVER_WS_URL="wss://license.rackvision.app"

Step 3: First Run

$ ./multiload_updater

  Activation Key: A3K7-XNPQ-8V2D-FWJT
  Contacting license server...
  License activated. Valid until 2026-04-18 12:00.

  Starting services...

License Lifecycle

TimeframeClient BehaviorServer Contact
Day 1–5Boots instantly, verifies locallyNot required
Day 5–7Watchdog tries to renew every 5 minAttempted, not required
Day 7+ (expired)Attempts renewal → exits if unreachableRequired
OngoingProactive renewal every 12hBest-effort

Revoking a Device

  1. Go to Devices tab → click Revoke.
  2. If the device is online, it receives a push and shuts down immediately.
  3. If offline, it will be blocked on next start or renewal attempt.

Troubleshooting

"License file is corrupted or tampered with"

Delete license.dat on the client and re-activate with a new key.

"License not valid for this machine"

Hardware/OS changed or license.dat copied from another machine. Delete and re-activate.

"Clock inconsistency detected"

System clock went backwards >1 hour. Fix NTP. Client will attempt server renewal automatically.

"License expired, server unreachable"

Restore network, restart the client. Renewal is automatic.

Environment Variables

License Server (.env)

VariableDescriptionDefault
PORTHTTP port4000
ADMIN_USERNAMEDashboard usernameadmin
ADMIN_PASSWORDDashboard password(required)
JWT_SECRETJWT signing secret(required)
SQL_SERVERMSSQL hostlocalhost
SQL_PORTMSSQL port1433
SQL_USERMSSQL user(required)
SQL_PASSWORDMSSQL password(required)
SQL_DBDatabase namerack_vision_license
ALLOWED_ORIGINSCORS origins(none)

Rust Client (.env)

VariableDescriptionDefault
LICENSE_SERVER_URLHTTP URL for activate/renewhttps://license.rackvision.app
LICENSE_SERVER_WS_URLWebSocket URL for heartbeatwss://license.rackvision.app

API Reference

License Endpoints (no auth)

MethodPathDescription
POST/api/license/activateActivate a device
POST/api/license/renewRenew a license
GET/api/public-keyGet Ed25519 public key
GET/api/healthHealth check

Admin Endpoints (JWT required)

MethodPathDescription
POST/api/admin/loginLogin, returns JWT
GET/api/admin/dashboardSummary stats
GET/api/admin/devicesList devices
GET/api/admin/devices/:idDevice detail
POST/api/admin/devices/:id/revokeRevoke device
POST/api/admin/devices/:id/unrevokeUnrevoke device
GET/api/admin/activation-keysList keys
POST/api/admin/activation-keysGenerate keys
PATCH/api/admin/activation-keys/:id/deactivateDeactivate key
GET/api/admin/audit-logAudit log
GET/api/admin/keysServer public key
POST/api/admin/keys/generateRotate key pair

WebSocket Endpoints

PathAuthPurpose
/ws/deviceQuery: device_id, license_id, fingerprintClient heartbeats
/ws/adminQuery: token (JWT)Dashboard updates