Skip to content

Authentication

qnop supports local accounts and external identity providers side by side. Both end at the same place: a signed access token plus a refresh cookie.

Self-registration with e-mail verification, password reset, and an administrator-initiated reset are all built in. Whether users may register themselves — and which role they get when they do — is set in Administration → Settings, not in the environment.

Local accounts need working SMTP for verification and reset mail. SMTP is also configured in the admin area.

Providers are registered at runtime under Administration → OIDC providers and stored in the database rather than in configuration files. Five types are supported — OIDC for any standards-compliant provider (Keycloak, Entra ID, Auth0 and the rest are configured as generic OIDC through their discovery document), plus GOOGLE, GITHUB, FACEBOOK and a generic OAUTH2 type.

Client secrets are encrypted at rest with QNOP_AUTH_ENCRYPTION_KEY, which is what makes rotating that key destructive — see Configuration.

Two behaviours are worth knowing before you enable a provider: an SSO login bypasses the self-registration setting, and every SSO user is provisioned as MEMBER with no linking to an existing account of the same e-mail address.

Setup walkthroughs for each provider, the callback-URL mechanics, the SSRF guard and the failure modes are covered in OIDC / OAuth 2.0 providers.

An access token is a short-lived JWT sent as a bearer token. Alongside it, a refresh token is issued in an HttpOnly cookie and rotates on use, so a stolen refresh token is usable at most once before the rotation is detected.

The cookie is marked Secure by default. A browser will therefore not send it over plain HTTP — which is a good default and the reason an HTTP-only deployment behaves as if login never sticks. Terminate TLS.

The authentication endpoints are individually rate limited — login, refresh, password change, registration and forgot-password each have their own budget, because they have different abuse profiles.

Every user holds exactly one global role:

RoleWhat it grants
ADMINthe administration area, the actuator endpoints, and the audit trail
MEMBERthe default — ordinary reviewing; access to individual documents is decided per resource by ownership and participation
AUDITORMEMBER, plus organisation-wide read access to the audit trail

Roles do not imply one another: ADMIN does not inherit AUDITOR, both are granted the audit surface explicitly.

Teams add a second, independent axis with LEAD and MEMBER. A team lead manages membership; the last lead of a team cannot be removed, so no team is ever left without one.