obsidian-vault/ligbox-ops-platform/specs/003-desk-auth-rbac/contracts/auth-api.md
2026-06-19 17:26:42 +00:00

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