Authentication
MaxTrax uses a self-hosted, stateless JWT identity model with two transports for the same token. This page describes the current (Wave 1) behaviour exactly as shipped. Self-serve OAuth2 client registration and scopes are Wave 2.
Two transports, one token (dual-mode)
Section titled “Two transports, one token (dual-mode)”The API issues a short-lived access token (a JWT) and a rotating, server-revocable refresh token. The same access token can be presented in either of two ways:
| Mode | Used by | How the token travels |
|---|---|---|
| Cookie | The MaxTrax web app (PWA) | HttpOnly cookies set by the /auth endpoints |
| Bearer | Server-to-server / early integrators | Authorization: Bearer <access-token> header |
The bearer middleware reads the token from the Authorization header when one is present, and
falls back to the cookie only when it is absent. So a non-browser integration that always sends the
header behaves like a classic bearer-token API — no cookies, no CSRF handshake.
Bearer mode (integrations)
Section titled “Bearer mode (integrations)”This is the mode to use for server-to-server integrations.
-
Sign in with
POST /auth/loginto obtain an access token (and a refresh token):Terminal window curl -X POST https://<your-tenant>.maxtrax.io/auth/login \-H 'Content-Type: application/json' \-d '{ "userName": "you@example.com", "password": "••••••••" }' -
Call the API with the access token as a bearer credential:
Terminal window curl https://<your-tenant>.maxtrax.io/welds \-H 'Authorization: Bearer <access-token>' -
Refresh when the access token expires, using
POST /auth/refresh. Refresh tokens rotate: each refresh returns a new refresh token and invalidates the previous one. -
Log out with
POST /auth/logoutto revoke the refresh token.
Because a bearer request carries no ambient cookie, no X-CSRF-Token header is required in this
mode.
Cookie mode (the web app)
Section titled “Cookie mode (the web app)”The first-party PWA never holds the raw token in JavaScript. On sign-in, the /auth endpoints set
three cookies:
mtx_at— the access JWT.HttpOnly; Secure; SameSite=Strict.mtx_rt— the rotating refresh token.HttpOnly; Secure; SameSite=Strict, path-scoped to/authso the long-lived credential rides only on/auth/refreshand/auth/logout.mtx_csrf— a non-HttpOnlydouble-submit nonce the SPA reads and echoes back.
Because cookies are ambient, cookie-authenticated unsafe requests (POST/PUT/PATCH/
DELETE) must include an X-CSRF-Token header equal to the mtx_csrf cookie value; a mismatch
returns 403. Fetch or rotate the nonce with GET /auth/csrf. Safe methods (GET/HEAD), bearer
requests, and anonymous endpoints are exempt. The app derives its signed-in state by probing
GET /auth/me.
Endpoint summary
Section titled “Endpoint summary”| Endpoint | Purpose |
|---|---|
POST /auth/login |
Sign in; issues access + refresh tokens (and sets cookies for browsers). |
POST /auth/refresh |
Exchange a refresh token for a new access token (refresh rotates). |
POST /auth/logout |
Revoke the refresh token and clear session cookies. |
GET /auth/me |
Return the current authenticated user. |
GET /auth/csrf |
Issue / rotate the mtx_csrf double-submit nonce (cookie mode). |
See the REST API reference for the exact request and response schemas.