Licensing
Pia Server reads its active licence at startup and exposes the current state on the License page (/admin/license).
Editions
Section titled “Editions”Edition is free text recorded at issue time. It changes nothing on its own — what a server can do comes
from the feature list and the seat limits inside the signed licence. Three are issued:
| Community | Cloud | Enterprise | |
|---|---|---|---|
| Local authentication, MFA, passkeys | Yes | Yes | Yes |
| AI proxy with your own provider keys | Yes | Yes | Yes |
| Sync and chat history | Yes | Yes | Yes |
| Admin dashboard, token board, runtime policies | Yes | Yes | Yes |
| Audit log and login-anomaly detection | Yes | Yes | Yes |
| End-to-end encryption, recovery, device management | Yes | Yes | Yes |
| Microsoft Entra ID SSO | — | Yes | Yes |
| Groups as the unit of policy | one default group |
Yes | Yes |
| Managed personas, client policies | — | Yes | Yes |
| Knowledge bases (RAG) | — | Yes | Yes |
| Users / admins | 5 / 1 | unlimited | per contract |
Community licences are free — see Getting a license.
The audit log, anomaly detection, encryption at rest, the token board and the runtime policies are not
licence-gated and work on every edition. Without GroupManagement, group, managed-persona and client-policy
writes are refused while reads stay open to any admin.
Guardrails, token limits, quotas, provider routing and the plugin allowlist carry no gate of their own, but
they are fields of the group — so changing them means editing a group, and a licence without
GroupManagement leaves them read-only at their seeded defaults. Guardrails are off in those defaults.
What’s on the License page
Section titled “What’s on the License page”The page has two tabs, Status and Events.
Under Status → Current license:
- Edition — the free-text edition recorded at issue time, e.g.
EnterpriseorCloud. - Licensed to — the email recorded when the licence was issued.
- Expires — a date, or Perpetual for a licence issued without one.
- Status —
Valid, or the reason it isn’t. - Features — a tick per entitlement:
LocalAuth,OAuth,AiProxy,Sync,AdminDashboard,E2EE,GroupManagement,Knowledge. TheKnowledgeflag gates the knowledge base (RAG): without it the KB stays off even with a vector DB configured. - Limits —
Max usersandMax admins, each shown as current / licensed.
The same data drives the global License status banner that appears across every admin page when the licence is missing, expired, near expiry, or a seat limit is reached.
Both seat counts read current / licensed on the Status tab — 2 / 5 means five are licensed and two are
in use. A licence issued with 0 for either means unlimited, and the page shows no ratio.
Max admins. Promoting an account to administrator is refused once the count would exceed the licensed
number. The refusal is recorded as an AdminLimitReached licence event on the Events tab, and the
banner across the top of every admin page reads:
Admin limit reached — This server is at its licensed admin limit (2 / 1).
Nothing is taken away when this appears: existing administrators keep working and every page stays
usable. It blocks only new grants. To clear it, either revoke an administrator you no longer need
(Accounts → the account → Revoke admin) or ask for a licence with a higher admin limit and
replace it. Note that an address listed in Admin:Emails is promoted at startup
and re-checked at sign-in, so trimming that list is usually the first step.
Max users. The seat check runs when a new account is provisioned through an identity provider: once
the licensed number is reached, the next new sign-in is refused and a UserLimitReached licence event is
recorded. Two banners precede it — a warning at 90% of the limit (“User limit nearly reached”), then an
error at the limit (“New sign-ups will be rejected”).
Freeing a seat is harder than it looks. Disabling an account does not free one. Neither does Soft-delete — and there the two numbers on screen can disagree, because the banner counts live accounts while the sign-up check counts every user row, soft-deleted ones included.
There is no per-account hard delete in the admin UI. What happens to a soft-deleted account depends on how its owner comes back:
- Signs in again through their identity provider → the account is restored, along with their soft-deleted templates, providers, sessions, memories, todos and kanban columns. Same seat, nothing new consumed. This is the designed path for “we deleted them by mistake”.
- Registers again with a password on the same address → the soft-deleted row is purged and a fresh account is created in its place. Still one seat.
So the practical levers when you are genuinely out of seats are to revoke access you no longer need and ask for a replacement licence with more seats. Do not reach for Settings → Data → Wipe → Users to make room: that storage area is all-or-nothing — every account, credential and cascaded record on the instance — not a way to remove one person.
License events
Section titled “License events”The Events tab on the same page is the licence audit trail — loaded, refreshed, replaced, expired,
plus the AdminLimitReached / UserLimitReached entries above. Repeats are deduplicated on a one-hour
window, so a limit that is being hit continuously produces at most one row per hour rather than one per
attempt — read the rows as “this was still happening at this time”, not as a count. This is the first
place to look when the server’s behaviour changed at a particular moment.
Getting a license
Section titled “Getting a license”Licences are signed offline and delivered as a .lic file — there is no self-service issuing page and no
issuing endpoint on your own server. Mail kontakt@pia-ai.de
with the edition, the seat counts and the features you need. Community licences are free; a licence issued
without an expiry date is perpetual.
The same route covers a licence you have outgrown: ask for a replacement with the higher limit and swap it in from the admin console. Nothing about the server changes — the entitlements live inside the signed file.
Installing a license on the server
Section titled “Installing a license on the server”The server reads one file, at License:Path — default ./license.lic next to the binary, and
/app/data/license.lic in both Compose files, which is on the mounted data volume so it survives a
container rebuild. Place the issued .lic there and start the server.
On a brand-new install there is no file yet, so the server comes up in setup mode and asks for the licence together with a setup token. See Admin overview → Activating a new install.
Replacing a licence
Section titled “Replacing a licence”To move to a bigger or renewed licence on a running server, use Replace license at the bottom of the
Status tab: drop in the .lic file or paste its contents and press Replace license. No setup token,
no restart — the provider reloads in place and the new entitlements apply to the next request.
The swap is guarded. The current file is copied to license.lic.bak first, the new content is written and
reloaded, and if it fails to validate the previous licence is restored and you get “The uploaded license
is invalid or has a bad signature. The previous license was restored.” A bad paste therefore cannot brick
the instance.
What happens when there’s no valid licence
Section titled “What happens when there’s no valid licence”An expired, missing or unreadable licence does not degrade the server to read-only — it stops it.
SetupModeMiddleware puts the whole instance back into setup mode:
- Browser requests are redirected to
/admin/setup. - API requests get
403with{"error":"no_license"}. - Only
/health,/auth,/admin/login,/admin/setupand the static/Blazor assets they need stay reachable — enough to sign in and paste a new licence, and nothing else. Sync, the AI proxy and every other admin page are unavailable.
Installing a valid licence restores full service immediately, with no restart. Because expiry is a hard stop rather than a soft one, watch the amber banner rather than waiting for the red one.