Authentication
Cookie sessions, bearer tokens, 2FA, SSO and the agent's own credentials.
Web sessions
The application signs in with POST /api/v1/auth/login and receives a JWT in an
HttpOnly cookie.
| Property | Value |
|---|---|
| TTL | 24 hours (JWT_TTL_HOURS) |
| Cookie | HttpOnly, SameSite, Secure when COOKIE_SECURE=true |
| Domain | COOKIE_DOMAIN |
| Claims | user id, organisation id, role |
The role travels in the token. That is why any role or membership change must
call RegisterUserLogout — otherwise a demoted user keeps the old permissions
until the token expires. See Roles.
Two-factor authentication
TOTP. POST /api/v1/auth/2fa/setup returns a secret and a QR payload;
/2fa/complete finishes a login that requires a second factor.
Two-factor can be enforced for an organisation, in which case members without it are required to enrol before they can do anything else.
Programmatic access
Settings → Team → API keys, or POST /api/v1/orgs/me/api-keys (admin).
curl -H "Authorization: Bearer $ACCELERUP_TOKEN" \
https://monitoring.qrdev.org/api/v1/services| Scope | The issuing organisation, and the issuing user's role |
| Shown | Once, at creation. It is not recoverable afterwards |
| Revoke | DELETE /api/v1/orgs/me/api-keys/{id} — immediate |
A token carries the role of the user who created it. An owner creating a
token for a script gives that script owner permissions. Create tokens from the
least-privileged account that can do the job.
Failed logins
Repeated failures lock the account. The lockout is per account, not per address, so it cannot be used to lock somebody else out by guessing from elsewhere — but it does mean a brute-force attempt will lock the real user out. That is the intended trade.
SSO
SAML and OIDC are available on the enterprise tier, with optional SCIM 2.0 provisioning. See SSO and enterprise.
SCIM uses its own subrouter and requires a token with the admin scope. It does
not use cookies and is not subject to CSRF protection, because it is a
machine-to-machine surface.
IP allowlisting
An organisation can restrict API access to a set of CIDRs. It is applied after authentication, so an allowlisted address still needs a valid token.
The agent
The agent does not use a JWT. It dials
GET /api/v1/agent/connect and authenticates with an enrolment token as a
bearer credential. That endpoint therefore sits outside the JWT-guarded group.
The terminal
A browser cannot set an Authorization header on a websocket. The
terminal is authenticated by a single-use ticket minted
by an ordinary authenticated POST /api/v1/agents/{id}/shell/ticket.
The ticket is what reaches the URL — not a JWT that would then sit in nginx logs, Cloudflare logs and browser history, valid for hours.
Ingest
/ingest/* uses a separate key (WEB_INGEST_KEY / WEB_INGEST_KEYS) because
it is called from browsers. See Ingest endpoints.
Where this behaviour lives: backend/internal/handler/middleware.go, backend/internal/service/auth_svc.go. If the code and this page disagree, the code is right — please fix the page.
Part of Reference — The exact numbers, names and limits, generated from the code.