Licensing
After the stack is up at http://localhost:3000, the next step is licensing the install. This page covers the three things you'll do once and then rarely revisit: retrieve this host's machine fingerprint, send it to your vendor, and install the signed .lic file you get back.
The licensing flow is fully offline. The application validates .lic files locally against a public key baked into the image. No network egress is required during install or at runtime.
What "licensed" means here
- A
.licfile is a small text file your vendor produces for your specific host. It's signed with the vendor's private key and lists the products and features you've purchased, your seat count, and your expiration date. - A license is node-locked by default: the file embeds a SHA-256 fingerprint of this host, and the install path checks that fingerprint against the running machine. A
.licissued for one host will not install on another. - A demo license is also supported — it ships with the image, doesn't need a fingerprint, and is intended for evaluation. When the demo expires, the application is read-only until you install a paid
.lic.
There's also an optional standalone License Server (a separate JAR) for customers who want LAN-wide seat reporting across multiple hosts. The single-host Docker Desktop install does not need it and this page does not cover it.
1. Retrieve this host's machine fingerprint
You have two ways to read the fingerprint. They produce the same value — pick whichever fits your workflow.
From the web UI
Sign in as an organization admin, then visit /licensing/installations/configure. The top card shows the fingerprint with a copy button, plus a breakdown of which hardware identifiers contributed to it.
The same string also appears on /licensing/installations/new so you can grab it without leaving the install page.
From the command line
If you'd rather not log in, exec into the running container:
docker compose exec deltamap bundle exec rake licensing:fingerprint
(Substitute your Compose service name for deltamap if you've renamed it.) The task prints a JSON object including a fingerprint: field — copy that value.
What the fingerprint depends on
On a default Docker Desktop install, the fingerprint hashes five values read from the running container:
- hostname
- primary MAC address
- CPU model
- root filesystem UUID
- motherboard serial
Replacing the host hardware or recreating the container with a different hostname will change the fingerprint and invalidate any node-locked license issued against the previous one. Routine docker compose down / up does not change the fingerprint as long as you keep the same container name and host.
If your environment locks down dmidecode or /sys/class/dmi/id/, some components will report as unknown — the fingerprint is still stable, it's just derived from a smaller component set. You can see exactly what was used on the configure screen.
2. Request your .lic from the vendor
Send your vendor an email (or open a support ticket) with:
- Your organization name as you want it to appear on the license.
- The fingerprint you just copied.
- The products you've purchased (e.g. deltamap, viz).
- The user-seat count you've purchased.
They'll generate a signed .lic file and send it back. It's a plain-text file you can cat — the readable header is informational; the cryptographic content is in the DATA: and SIGNATURE: lines at the bottom.
Treat the .lic file like a license certificate: it's not secret, but it's only useful on the host whose fingerprint it was issued against, and modifying it invalidates the signature.
3. Install the .lic file
In the web UI, go to Licensing → Install License (or visit /licensing/installations/new directly). Pick Install License File, choose your .lic, confirm, and submit.
On success the page redirects to Licensing → Status and the file is now persisted in PostgreSQL. The license expires at the date inside the signed payload — not based on when you uploaded it. Reinstalling later does not reset the expiration.
If validation fails, the most common reasons are:
| Error | What it means |
|---|---|
| "Signature verification failed" | The file is for a different vendor build (different public key), or the file was modified after signing. Re-request from the vendor. |
| "License has expired" | The signed expires_at is in the past. Renew with the vendor. |
| "Machine fingerprint mismatch" | The .lic was issued against a fingerprint that doesn't match this host. Re-run step 1 and re-request. |
4. Check status
/licensing/installations/status shows the active license: customer, type, expiration, the list of licensed features, and (for node-locked licenses) the bound fingerprint. Organization admins additionally see the license key and installation ID for support-ticket use; non-admins see the same status without those identifiers.
The status page is intentionally reachable even when the build itself has expired — it's the surface from which you'd diagnose why the app is locked.
5. Replace or renew a license
To install a renewal .lic, repeat step 3. The new file replaces the old one transactionally: if validation fails, the previous license stays active.
To rotate to a different license entirely (different products, different fingerprint after a hardware change), the same flow applies. There is no "uninstall" step required first.
After the demo expires
If you've been running on the bundled demo and it lapses before your purchased .lic arrives, the application redirects most requests to a "build expired" page. The licensing pages remain reachable:
/licensing/installations/status— see what state you're in/licensing/installations/configure— read the fingerprint/licensing/installations/new— upload the new.lic
Once a paid (non-demo) .lic is installed, the build-expiration gate disengages and full access returns immediately.
Air-gap considerations
The above flow is already offline-compatible — the .lic file is the only thing that crosses the boundary, and it can travel by email, USB, or any other side channel. The application makes no network calls during validation. If you set up the optional license server later, see the OpenShift section's deployment guide for the LAN-mTLS reference architecture.