Authentication API
Token-based authentication with RBAC (Role-Based Access Control). Mango serves as the identity provider for the entire ZERG platform.
Overview
Authentication flows through Mango (Python/Tornado). Users authenticate via credentials, receive a Bearer token, and that token is validated by Sol's auth middleware on every request. Permissions flow through ZMQ to workers for consistent enforcement.
Endpoints
Login
POST /auth/loginRequest Body:
{
"username": "alice",
"password": "s3cret!",
"grant_type": "password"
}Response:
{
"access_token": "zerg_mg_abc123def456",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "chat:read chat:write goals:*"
}The token can be used as Authorization: Bearer <access_token> on all subsequent requests.
Refresh Token
POST /auth/loginRequest Body:
{
"grant_type": "refresh_token",
"refresh_token": "..."
}Returns 401 — refresh tokens are explicitly rejected by Mango. Clients should re-authenticate.
Token Validation (Internal)
POST /api/v1/auth/validateUsed internally by Sol to validate tokens. Not exposed for external use.
Logout
POST /api/v1/auth/logoutInvalidates the current token. Returns 204 with no body.
RBAC
Permission Model
Permissions are resolved through the chain:
User → UserTeams → TeamRoles → Roles.Permissions| Component | Description |
|---|---|
| Users | Identified by UUID, linked to teams |
| Teams | Groups with shared role assignments |
| Roles | Named permission sets (admin, operator, viewer) |
| Permissions | resource:action strings (e.g. chat:read, goals:*) |
Admin role requires permissions containing ["*"]. The admin bootstrap script is at mango/scripts/bootstrap_admin.py.
Session Cookie
WebSocket chat uses the zerg_session cookie for auth:
Set-Cookie: zerg_session=<token>; HttpOnly; Secure; SameSite=Strict; Path=/The cookie is set by Mango on successful login. It is secondary to the Authorization header — the header takes priority when both are present.
Error Codes:
| Code | Description |
|---|---|
| 401 | Invalid credentials or expired token |
| 403 | Insufficient permissions |
| 429 | Rate limit exceeded |
Examples:
curl -X POST http://127.0.0.1:8080/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"username": "alice", "password": "s3cret!", "grant_type": "password"}'
curl http://127.0.0.1:11434/api/v1/models \
-H "Authorization: Bearer $TOKEN"