Auth flow¶
Scripts and automations use the bearer flow: login returns an access token that goes into the Authorization header. The web app itself uses a separate cookie flow (HttpOnly cookies plus CSRF token) — your own clients should use the bearer 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":"..."}'
The field is called email; for a sign-in via Active Directory / LDAP it holds the directory user name.
Response (without 2FA)¶
{
"access_token": "eyJhbGc...",
"token_type": "bearer",
"expires_in": 43200,
"requires_2fa": false
}
The access token is valid for 12 hours. There is no separate refresh token in the bearer flow.
Response (with 2FA)¶
{
"requires_2fa": true,
"two_fa_method": "totp",
"two_fa_factors": ["totp", "backup_code"],
"pending_token": "eyJhbGc..."
}
two_fa_factors lists the second factors the account actually has set up. The pending_token is valid for 5 minutes and only works for step 2.
Step 2 — Verify 2FA¶
curl -X POST https://your-domain.tld/api/v1/auth/2fa/verify \
-H "Authorization: Bearer <pending_token>" \
-H "Content-Type: application/json" \
-d '{"code":"123456"}'
code takes a TOTP code or a backup code. For a passkey, first call POST /api/v1/auth/2fa/webauthn/begin (also with the pending_token), then send {"method":"webauthn","challenge_id":"…","response":{…}}.
Response¶
Wrong code: 401. After 5 failed attempts the second factor is locked for 30 minutes: 429 with Retry-After.
Step 3 — Requests with the token¶
Renewal¶
curl -X POST https://your-domain.tld/api/v1/auth/refresh \
-H "Authorization: Bearer <access_token>"
Exchanges a still-valid access token for a new one (again 12 hours). The chain ends at the absolute session limit from Sessions — then 401 and sign in again. An expired token cannot be renewed.
A token becomes invalid immediately when the account is deactivated or deleted, its role or tenant assignment changes, an admin resets the password, or the user changes their own password or chooses "Sign out everywhere else".
Logout¶
POST /api/v1/auth/logout ends the web app's cookie session. It has no effect for bearer clients — just discard the token; it expires after 12 hours at most.
Step-up (sensitive actions)¶
Sensitive actions (e.g. creating users, generating keys, changing scripts, security settings) require a fresh identity confirmation. A fresh login counts as confirmation for 15 minutes; after that such endpoints answer 403 with
Confirm:
curl -X POST https://your-domain.tld/api/v1/auth/step-up \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"method":"totp","code":"123456"}'
method is one of the ways GET /api/v1/auth/step-up/status offers under methods (password with field password, totp or backup_code with code, webauthn). The confirmation lasts 15 minutes.
Collector and agent keys are not user auth¶
Collectors authenticate with an API key (X-API-Key header, stored only as a SHA256 hash), agents with an agent token (X-Agent-Token header). Both only work for the paths collector and agent need themselves (submitting results, configuration and heartbeat) — they are not a replacement for login and don't work on any user endpoint (hosts, profiles, dashboards etc.). Scripts/CI that call the user API use the login flow above; there are no personal API tokens for users. A dedicated service account with a suitable role is the usual approach.
A collector key is created when a collector is added and shown once in plain text; an agent token is created when an agent is set up on a host. Each belongs to exactly one resource (collector or host), not to a user.
Missing permission¶
If a permission is missing, the endpoint answers 403, e.g.:
Objects of other tenants answer 404, not 403.
Tenant scope¶
The token carries account, role and home tenant. Which tenants an account sees and which role applies in which tenant is checked by the server on every request against the current assignment (see Roles). List endpoints usually take ?tenant_id=<uuid> as a filter; without it you get all tenants the account has access to.
Rate limits¶
- Login, 2FA verification, passkey challenge and step-up: 10 requests/minute per client IP
- Other endpoints: no dedicated limit
When exceeded: 429.
Time sync¶
Token validity depends on the server clock. If it's wrong (no NTP), you get seemingly random 401 errors.
Next¶
- API reference
- Cookbook — code snippets
- 2FA
- Sessions