License lifecycle
proHow Pro licenses are issued, refreshed, and revoked.
Pro licenses are signed (Ed25519) by grith.ai's release key and stored locally
under ~/.config/grith/licenses/. Every Pro feature gates on a valid local
license file; the grith.ai service only sees a refresh ping every few hours, not
the actual feature usage.
Lifecycle states
not-enrolled ──login──▶ active ──expires-soon──▶ active (warn)
│
├──6h refresh window──▶ refreshed
│
├──refresh-fails──▶ cached (24h grace)
│
└──revoked-by-admin──▶ revoked ──fallback──▶ community
| State | Behaviour |
|---|---|
not-enrolled | No license file. Pro features locked; community features fine. |
active | License valid. Pro features work. |
active (warn) | Within 14 days of expiry. Dashboard shows a warning. |
cached | License is valid but the most recent refresh failed (network). 24h grace before downgrade. |
revoked | License invalidated by team admin. Falls back to community tier on next call. |
Refresh
The daemon refreshes the license in the background every 6 hours. What gets sent to grith.ai on refresh:
- Team ID
- Device fingerprint (hash of stable hardware IDs)
- Current license signature
- Grith version
What gets returned:
- New signed license (with extended
valid_until) - Or
revoked: trueif the team admin has revoked this device
The refresh does NOT send:
- Audit data
- Reputation state
- Any session content
Force refresh:
grith pro refresh
Expiry
When a license approaches expiry:
- 14 days out — dashboard shows a warning banner.
- 48 hours out — daemon emits an
infoaudit event each day. - at expiry — features lock out only after a final refresh attempt fails. If refresh succeeds at expiry minute (because billing has been renewed), no interruption.
Revocation
A team admin can revoke a device's seat from the dashboard. The next refresh
returns revoked: true; grith locks out Pro features and switches the device
to community-tier behaviour without interrupting in-flight sessions.
Offline / network-restricted operation
If a device can't reach grith.ai for refresh:
- 0–24h after the last successful refresh: full Pro features still work (cached state).
- 24h+ without refresh: Pro features lock out, community continues to work.
For genuinely air-gapped environments, see Air-gapped deployment (Enterprise feature, planned).
License file format
The local license file is a signed CBOR blob. Schema:
{
"version": 1,
"team_id": "...",
"device_id": "...",
"plan": "pro | enterprise",
"seats": 25,
"features": ["team-sync", "encrypted-keys", "analytics", ...],
"issued_at": "2026-05-01T00:00:00Z",
"valid_until": "2026-05-15T00:00:00Z",
"next_refresh": "2026-05-14T06:00:00Z"
}
Plus an Ed25519 signature over the canonical CBOR.