-
Notifications
You must be signed in to change notification settings - Fork 0
Feature License
English · Tiếng Việt · 中文
Since 1.6.0, SkimMail is free to self-host forever at the Community tier, with a small set of per-instance limits, and unlocks higher tiers through an offline, signed license key — no license server, no phone-home requirement to apply one, and no account of any kind on SkimMail's side.
Self-hosted software that wants to fund itself usually picks one of two unpleasant options: cripple the free tier so hard it isn't really usable, or require a running license server that turns a self-hosted product into one more thing that can go down and lock you out of your own mail. SkimMail's entitlement system is neither: Community Edition is a complete, real mailbox reader with generous-enough limits for one person, and a key that unlocks more is a signed, offline token you paste in once — verified with cryptography already built into the binary, never checked against a remote server at apply-time.
Settings ▸ Plan & License, owner only.
| Resource | Community | Sponsor | Pro |
|---|---|---|---|
| Accounts | 10 | 25 | Unlimited |
| Connections (egress proxies/tunnels) | 3 | 5 | Unlimited |
| Groups | 2 | 5 | Unlimited |
| Storage | 5 GB (display only — see below) | 15 GB (display only) | Unlimited |
Sign-ins (AUTH_MODE=users) |
1 | 3 | Unlimited |
Community is the fallback whenever no license is applied, or an applied one has expired or been revoked. Sponsor's sign-in limit of 3 is the smallest number at which the owner/operator/viewer role model (see Users and roles) means anything at all — Community's other numbers describe one person with a real setup, not a team.
These limits are per instance, not per user. Counting them per user would let anyone lift the Community 10-account cap by creating a second sign-in; the counts behind every meter here are unscoped queries against the whole database on purpose.
Paste the license text, or drop the file it came in, and save. A key is a
compact two-part token — a JSON payload and an Ed25519 signature, both
base64url-encoded, joined by a . — verified against a public key baked into
the binary at build time. Nothing is sent anywhere to apply it: the whole
check happens locally, so it works on an air-gapped instance exactly as well
as an internet-connected one.
A key with a bad or missing signature is refused outright (nothing is stored) and the screen reports it as invalid. A key that verifies but has already expired is still stored and shown — its tier, licensee name and dates are displayed for transparency — while every limit in effect falls back fully to Community until you apply a current one. Replacing an existing key, or removing it entirely to revert to Community, are both one click away on this screen.
Entitlement gates creation only — never recovery, never reading. If a Sponsor key lapses while you have 22 accounts configured, none of them disappear, stop syncing, or become read-only: all 22 keep working exactly as before. What changes is that you cannot add a 23rd account, connection or group until you either renew the key or delete down to the Community ceiling. The same instinct explains why storage is never enforced at all — see below.
The UI treats expired and revoked as related but distinct: a revoked key (one whose id appears on SkimMail's signed revocation list) is labelled as revoked rather than merely expired, so you know to ask about the license itself rather than assume your subscription simply ran out.
Every SkimMail build carries a baked-in baseline of revoked license ids, which alone is enough to work forever on an offline instance. On top of that, an instance that has opted into the periodic self-update check (see Operations) piggybacks a fetch of the latest signed revocation list on the same cycle — never a separate network dependency of its own — and only accepts a fetched list if it is strictly newer than whatever is already cached, specifically to stop a network attacker from replaying an old, genuinely-signed list forever to hide a revocation you would otherwise have learned about. Any failure here — offline, update-checking turned off, a bad signature — is silently swallowed and simply leaves the baked-in baseline as the floor; it never blocks anything else in the product.
The four numbers above are not enforced identically:
- Accounts, connections and groups are checked at the moment you try to create one more — adding an IMAP or OAuth account, adding an egress proxy/tunnel, or adding a group all refuse with "limit reached" once you are at the tier's ceiling.
-
Sign-ins are checked the same way, but only from the
skimmail user addCLI (see Users and roles) — there is no self-serve "create a user" screen in the product for this to gate in the UI. -
Storage is never enforced, on purpose. The number shown is a real
filepath.Walkover your data directory, computed fresh each time you open this screen, but it is display-only: nothing in SkimMail refuses a write — a mail sync saving an attachment, a body being cached — because you are over a storage number. The alternative (a mailbox that stops accepting new mail because a disk got full according to a number on a settings screen) was judged worse than an honest, unenforced meter.
| Available since | 1.6.0 |
| Role | owner |
| Tiers | Community · Sponsor · Pro |
| Enforcement point | account/connection/group creation, and skimmail user add; never storage |
| Network required to apply a key | No |
| Network required to check revocation | No — best-effort, piggybacked on the opt-in update check |
- It gates no content. Message count, mailbox size, and cached body size are unaffected by tier — only the number of accounts, connections and groups you can create, and how many people can sign in.
- It does not phone home to apply or verify a key. The signature check is entirely local; only the optional revocation-list refresh ever makes a network call, and it never blocks applying or using a key.
-
The verification key cannot be overridden by an environment variable,
unlike the self-update key (
UPDATE_PUBKEY). It is a build-time constant on purpose — an env override would let anyone generate their own keypair and self-sign an "unlimited" license in two commands, which would defeat the entire system. -
It cannot restore something a limit is now blocking. Deleting down to
the Community ceiling is manual, and — per Users and roles — deleting the
wrong user account under a 1-seat limit can be a genuine bind; the CLI has
a
--reassign-tooption for exactly that case.
-
Users and roles — the sign-in limit, the
skimmail userCLI, and what a 1-seat Community instance means for deleting a user - Operations — the opt-in update check the revocation-list refresh rides along with
-
LICENSE/COMMERCIAL-TERMS.mdin the repository — the legal terms behind the tiers; this page describes only how the software behaves
SkimMail · skimmail@base101.app · 2026-09-15 · commit dffbb18