# 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 ` **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. ```http POST /api/v1/auth/login HTTP/1.1 Content-Type: application/json { "username": "root", "password": "805353" } ``` ### Response 200 ```json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 28800, "username": "root", "role": "super_admin", "display_name": "Roger" } ``` ### Response 401 ```json { "detail": "invalid credentials" } ``` ### Response 429 ```json { "detail": "too many login attempts" } ``` --- ## GET /api/v1/auth/me ```http GET /api/v1/auth/me HTTP/1.1 Authorization: Bearer ``` ### Response 200 ```json { "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) ```http GET /api/v1/desk/tickets HTTP/1.1 Authorization: Bearer ``` ### Sem token → 401 ```json { "detail": "not authenticated" } ``` ### noc → 200 com dados mascarados `company_profile.tax_id` e morada omitidos/mascarados. --- ## PATCH /api/v1/desk/tickets/{id} ```http PATCH /api/v1/desk/tickets/11 HTTP/1.1 Authorization: Bearer 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) ```http POST /api/v1/webhooks/onboard HTTP/1.1 Content-Type: application/json X-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) ```http GET /health HTTP/1.1 ``` Sempre 200 sem auth (Traefik healthcheck). --- ## Role test matrix (curl) ```bash 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 |