3.3 KiB
3.3 KiB
API Contract: Desk Auth & RBAC
Service: Ligbox Ops Platform API (VM122)
Base URL (LAN): http://10.10.10.122:8080
Base URL (público): https://api.ops.ligbox.com.br
Human Auth: Authorization: Bearer <JWT>
Machine Auth: X-Webhook-Secret (webhooks only)
Internal Auth: X-Ops-Internal-Token (worker audit cycle)
POST /api/v1/auth/login
Público. Não requer JWT.
POST /api/v1/auth/login HTTP/1.1
Content-Type: application/json
{
"username": "root",
"password": "805353"
}
Response 200
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 28800,
"username": "root",
"role": "super_admin",
"display_name": "Roger"
}
Response 401
{ "detail": "invalid credentials" }
Response 429
{ "detail": "too many login attempts" }
GET /api/v1/auth/me
GET /api/v1/auth/me HTTP/1.1
Authorization: Bearer <token>
Response 200
{
"username": "mini",
"role": "technician",
"display_name": "Suporte",
"active": true,
"last_login_at": "2026-06-10T12:00:00+00:00"
}
GET /api/v1/desk/tickets (protegido)
GET /api/v1/desk/tickets HTTP/1.1
Authorization: Bearer <token>
Sem token → 401
{ "detail": "not authenticated" }
noc → 200 com dados mascarados
company_profile.tax_id e morada omitidos/mascarados.
PATCH /api/v1/desk/tickets/{id}
PATCH /api/v1/desk/tickets/11 HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
{
"status": "closed",
"assigned_to": "mini"
}
| Role | Resultado |
|---|---|
| super_admin, ops_lead | 200 |
| technician (assigned ou unassigned) | 200 |
| technician (assigned to other) | 403 |
| noc | 403 |
Webhook (inalterado — sem JWT)
POST /api/v1/webhooks/onboard HTTP/1.1
Content-Type: application/json
X-Webhook-Secret: <WEBHOOK_SECRET>
{"event":"account.created","domain":"test.ligbox","session_id":"x"}
JWT no lugar do secret → 401 (webhooks não aceitam Bearer).
Health (público)
GET /health HTTP/1.1
Sempre 200 sem auth (Traefik healthcheck).
Role test matrix (curl)
API="http://10.10.10.122:8080"
TOKEN_ROOT=$(curl -sf -X POST "$API/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"root","password":"805353"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# Deve falhar sem token
curl -sf "$API/api/v1/desk/tickets" && echo UNEXPECTED || echo "401 OK"
# Deve funcionar com token
curl -sf -H "Authorization: Bearer $TOKEN_ROOT" "$API/api/v1/desk/tickets" | head -c 80
TOKEN_NOC=$(curl -sf -X POST "$API/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"noc","password":"805353"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# noc não pode fechar ticket
curl -sf -X PATCH -H "Authorization: Bearer $TOKEN_NOC" \
-H "Content-Type: application/json" \
-d '{"status":"closed"}' \
"$API/api/v1/desk/tickets/1" && echo UNEXPECTED || echo "403 OK"
Error codes
| HTTP | Significado |
|---|---|
| 401 | Sem token, token inválido/expirado, credenciais login erradas |
| 403 | Token válido mas role insuficiente |
| 429 | Rate limit login |