Skip to navigation

Authentication

JWT sessions for people, API keys for edge devices.
View as Markdown

Cargovision has two separate authentication mechanisms. Use the one that matches the caller, and never substitute one for the other.

CallerMechanismUsed for
People: web dashboard, mobile app, scripts acting for a userJWT in the token cookie or an Authorization: Bearer <jwt> headerEvery /v1/* endpoint except edge ingestion
Trusted edge devicesStatic API key in an X-API-Key: <key> header/v1/edge/* writes and POST /v1/tracking-data/stream-events

JWT sessions

Sign in

MethodEndpointPurpose
POST/v1/user/auth/email/loginSign in with email and password
GET/v1/user/auth/googleStart Google sign-in; on success the API sets the session cookie and redirects back to the web app
GET/v1/user/auth/refresh-tokenIssue a fresh token for the current session; returns the user’s email and role
GET/v1/user/auth/logoutClear the session cookie

A successful sign-in sets an HttpOnly, SameSite=Strict cookie named token that holds the JWT (Secure in production, Path=/, Max-Age of 7 days). Browsers send it automatically. Non-browser clients can read the cookie and send its value as a bearer token instead:

Authorization: Bearer <jwt>

Call GET /v1/user/auth/refresh-token to rotate the token. It requires a valid token and returns a new token cookie.

Accounts

New accounts are created by invitation. Administrators issue invites from the dashboard, and the invite link lets the recipient set a password. Password resets use POST /v1/user/auth/email/forgot-password followed by PUT /v1/user/auth/email/change-password with the emailed token.

Roles

Every user has one of three roles. The API enforces them on every request; the dashboard’s role-based UI is a convenience, not the security boundary.

RoleAccess
operatorContainers the user owns, plus shared registries such as cameras and topology
supervisorEverything an operator can do, plus every container, the escalation queue, and manual review
adminEverything a supervisor can do, plus /v1/admin/*: users, invites, edge devices, audit log, and email jobs

A missing or invalid token returns 401. A valid token without the required role returns 403.

Requests that change data (POST, PUT, PATCH, DELETE) and authenticate with the token cookie must come from a trusted origin, checked through the Origin or Referer header. Otherwise the API returns 403 with Forbidden: untrusted request origin. Requests that send an Authorization: Bearer header skip this check, so scripts and mobile clients should use the bearer header.

Rate limits

Credential endpoints are rate limited per IP address over a 15-minute window:

EndpointLimit
POST /v1/user/auth/email/login5 failed attempts; successful sign-ins don’t count
verify, register, forgot-password, change-password under /v1/user/auth/email5 requests
Public invite preview and accept under /v1/invites/{token}30 requests

Exceeding a limit returns 429. Standard RateLimit-* headers report the remaining budget.

Edge device API keys

Edge devices authenticate with a static key configured on both the API and the device. Send it in the X-API-Key header:

curl -sS -X POST https://api.cargovision.app/v1/edge/containers/identify \
-H "X-API-Key: $CARGOVISION_EDGE_API_KEY" \
-H "Content-Type: application/json" \
-d @identify.json

Authorization: Bearer <api-key> is accepted as an alternative. A missing key returns 401 MISSING_API_KEY; a wrong key returns 401 INVALID_API_KEY.

The edge API key grants write access to inspection data. Keep it on the edge device and on servers you control. Never ship it in browser or mobile code.