v0.28.0
Headline: air-gapped licensing. Monitors can now run paid tiers with zero outbound network, and every license validation is now cryptographically signed and verified locally.
✨ Air-gapped / offline licensing
- Run Pro/Enterprise in fully air-gapped or offline environments. Download a signed offline license token from your account page (betterdb.com/account/licenses → Download) and activate it - the monitor verifies it locally against embedded public keys, with no phone-home.
- Activate it two ways:
- UI: Settings → License → "Air-gapped environment? Activate an offline license" (paste the token or upload the
.jwtfile). - Config:
BETTERDB_OFFLINE_LICENSE(token string) orBETTERDB_OFFLINE_LICENSE_FILE(path to a mounted.jwt).
- UI: Settings → License → "Air-gapped environment? Activate an offline license" (paste the token or upload the
- When running purely from an offline token (no license key configured), telemetry and phone-home are automatically disabled - nothing leaves the box.
- Licenses are floating (advisory instance limit); re-download a fresh token to renew before it expires.
🔒 Signed, tamper-proof entitlements
- Online validation now returns an RS256-signed entitlement token that the monitor verifies locally - a spoofed or compromised endpoint can no longer grant a tier.
- The verified token is persisted and used as a fallback during entitlement-server outages or restarts, so your paid tier survives connectivity blips instead of dropping to community.
- Verification precedence: fresh online → in-memory cache → persisted signed token → offline token → community.
📊 Status & UI
GET /license/statusnow reportssource(online/cached/persisted-jwt/offline-token/community),mode,instanceLimit,offlineExpiresAt, andclockRollbackSuspected.- Expiry warnings surface at 30 and 7 days; advisory clock-rollback detection.
⚙ New configuration
| Env var | Purpose |
|---|---|
BETTERDB_OFFLINE_LICENSE |
Offline license token (string) |
BETTERDB_OFFLINE_LICENSE_FILE |
Path to an offline license .jwt (e.g. a mounted secret) |
BETTERDB_DATA_DIR |
Where license state is persisted (license.jwt, license-offline.jwt, license-clock.json; default ./data, files written 0600) |
🐛 Fixes & hardening
- Paid tier no longer briefly flashes to community during offline-license activation or license refresh.
- Real/perpetual license expiry is reported correctly during outages (not the short token window).
- Offline-expiry enforcement on read paths;
kid-based signing-key rotation support.
⬆ Upgrade notes
- Fully backward compatible. Existing
BETTERDB_LICENSE_KEY(online) deployments keep working unchanged - they additionally get a signed token cached for outage resilience. No action needed unless you want air-gapped operation. - If you want license state to survive restarts, mount a writable volume at
./data(or setBETTERDB_DATA_DIR).
🐳 Docker
docker pull betterdb/monitor:0.28.0What's Changed
Full Changelog: v0.27.0...v0.28.0