52 lines
2.5 KiB
Markdown
52 lines
2.5 KiB
Markdown
---
|
|
paths:
|
|
- "licensing-service-startos/licensing-service/src/license_self.rs"
|
|
- "licensing-service-startos/licensing-service/src/api/tier.rs"
|
|
- "licensing-service-startos/licensing-service/src/api/self_license.rs"
|
|
- "licensing-service-startos/licensing-service/src/upgrades.rs"
|
|
- "licensing-service-startos/licensing-service/src/api/upgrade.rs"
|
|
---
|
|
|
|
# Self-license & tier gating
|
|
|
|
The daemon licenses **itself** via its own licensing scheme — the operator runs a
|
|
master Keysat that issues the license this instance validates.
|
|
|
|
## Always boots — no enforce mode
|
|
|
|
Enforce mode was **retired**: there is no `KEYSAT_LICENSE_ENFORCE` build flag and
|
|
`check_at_boot` (`license_self.rs`) always returns `Ok`. A missing/invalid
|
|
self-license logs a warning and the daemon runs at the free **Creator** tier
|
|
(`Tier::Unlicensed`, surfaced as "Creator" in the admin UI) with Creator caps —
|
|
**5 products, 5 policies per product, 10 active discount codes**. Activating a
|
|
license lifts those caps and unlocks `recurring_billing` + `zaprite_payments`.
|
|
Treat any "marketplace build refuses to start without a license" wording in code
|
|
comments or copy as stale.
|
|
|
|
## Live entitlements, clamped to the signed key
|
|
|
|
Tier gates read **live** entitlements from `licenses.entitlements`, refreshed
|
|
hourly by `refresh_self_tier_from_db` in `license_self.rs`, so issuer-applied
|
|
**downgrades, suspensions, and revocations** — plus the key's own **expiry**
|
|
(the refresh re-verifies the on-disk key, demoting an expired one) — reach a
|
|
running daemon without a restart. The signed self-license key is the
|
|
**ceiling**: the live DB row may
|
|
*narrow* the tier but never *widen* it past what the signature grants
|
|
(`clamp_to_signed_ceiling`). A genuine **upgrade** therefore comes from a
|
|
re-issued key — re-run the StartOS "Activate Keysat license" action — not from
|
|
editing the DB row.
|
|
|
|
## Never silently widen a tier
|
|
|
|
Do **not** expand entitlements in `tier::current()` (e.g. "patron implies pro").
|
|
Tried in `0.2.0:41`, reverted in `0.2.0:42`. When an operator is stuck on an
|
|
old-scheme self-license, the correct fix is: **re-issue** the license + run the
|
|
StartOS "Activate Keysat license" action — the new key overwrites
|
|
`/data/keysat-license.txt` and `self_tier` refreshes without a daemon restart.
|
|
|
|
## Entitlements in flight
|
|
|
|
`unlimited_merchant_profiles` (Creator = 1 merchant profile, Pro/Patron =
|
|
unlimited) still needs adding to the master Keysat's Pro/Patron policies — a data
|
|
action on the keysat.xyz admin, no code. See [payments](payments.md).
|