A license system for software that runs entirely on someone else's network has one hard constraint: it must never grant unlimited access simply because it can't reach home. This page describes exactly how TuneVault avoids that trap.
| Cloud | Self-hosted | |
|---|---|---|
| Where limits live | user_credits.plan_tier, checked per-request |
A license key, validated against tunevault.app |
| Enforcement point | tier-enforce.js middleware on connection creation and health-check runs |
The same middleware, reading caps resolved from the license instead of a plan row |
| What happens over cap | HTTP 402 with a structured upgrade message | HTTP 402, same shape — expired trials get an expiry-specific message |
Self-hosted TuneVault's core audience is enterprises whose firewalls block outbound connections by default — the exact ICP this product exists for. That creates an uncomfortable tension: if the license server is unreachable, do you brick a legitimate paying customer's install, or do you grant unlimited access because you can't check?
Neither. TuneVault caches the result of every successful validation, keyed to the license key that earned it:
The critical line is the third one. A cache keyed only on "does a row exist" would let someone swap in a forged key, block outbound access, and inherit whatever caps happened to be cached — so the cache also records which key earned it, and a mismatched key is treated as never-validated.
A container started once and never restarted would otherwise keep its boot-time caps forever — meaning a 30-day trial license would never actually expire in practice. Caps are instead resolved fresh at the point of use, via a shared helper checked by every enforcement site, rather than read once from a value set at startup.
Once a license's expires_at has passed, existing connections and their historical reports and tickets stay fully readable — nothing is deleted or hidden. What stops is new health checks, which is where the actual ongoing value of the product lives. This is a deliberate design choice: an expired trial should make its absence felt, not disappear the evidence of what it already found.
| Property | Value |
|---|---|
| Connections | 1 |
| Health checks | Unlimited |
| Duration | 30 days from issue |
| Cost to issue | None — self-hosted runs on your hardware with your own optional AI keys, so a trial connection costs TuneVault nothing to support |
One connection with unlimited checks was a deliberate choice over a small number of checks with more connections: the value of TuneVault only becomes visible when someone watches it catch something real on their own database over time, and a check-count limit would cut that observation short before it happens.