Auth flow¶
Step 1 — Login¶
curl -X POST https://your-domain.tld/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"..."}'
Response (without 2FA)¶
{
"access_token": "eyJhbGc...",
"refresh_token": "eyJhbGc...",
"token_type": "bearer",
"expires_in": 86400
}
Response (with 2FA)¶
The user has 2FA enabled (authenticator app or passkey). Continue with the challenge_token and the TOTP code:
Step 2 — Verify 2FA¶
curl -X POST https://your-domain.tld/api/v1/auth/2fa/verify \
-H "Content-Type: application/json" \
-d '{"challenge_token":"tx_...","code":"123456"}'
Response¶
Wrong code: 401 + attempts_remaining in body. After 5 failures: 429 + Retry-After: 1800.
Step 3 — Requests with JWT¶
Refresh¶
curl -X POST https://your-domain.tld/api/v1/auth/refresh \
-H "Authorization: Bearer <refresh_token>"
Returns a new access_token (and new refresh_token). Refresh token is single-use.
Logout¶
Server invalidates the refresh token, frontend discards the access token.
Collector API keys are not user auth¶
Collectors authenticate with their own API key (X-API-Key header, stored as
a SHA256 hash), agents with their own agent token (X-Agent-Token header).
Both are accepted exclusively by the receiver for check-result uploads — they
are not a substitute for the JWT login and don't work against any
/api/v1/ user endpoint (hosts, profiles, dashboards, etc.). For
scripts/CI that need to talk to the user API, the regular login flow above
(email/password → JWT) is the only path — there is currently no separate
API-key concept for users.
A collector key is created when you add a collector (/collectors in the
frontend) and shown once in plaintext there; an agent token is created when
you set up an agent on a host. Both belong to exactly one resource
(collector or host), not to a user.
Permission failures¶
Missing permission:
HTTP 403.
Tenant scope¶
JWT contains tenant_id (own tenant) and tenant_scope (null for super admin, otherwise tenant UUID).
Cross-tenant queries (super admin) optional via query: ?tenant_id=<uuid>. Without query you get your own tenant.
Rate limits¶
- Login/2FA: 10 req/min per IP
- Other endpoints: 600 req/min per user
On exceed: 429 + Retry-After.
Time sync¶
JWT exp claim assumes client and server are time-synced (default 30 s tolerance). With server clock wrong (no NTP), phantom 401 errors appear.
Next¶
- API reference
- Cookbook — code snippets
- 2FA