Sari la conținut

Autentificare și chei API

Programele se autentifică la API-ul PlusPanel cu o cheie API trimisă ca bearer token. Panoul folosește o sesiune de browser; CLI-ul poate obține o cheie pentru tine printr-o autentificare în browser (device flow).

GET /api/v1/auth/me HTTP/1.1
Host: panel.example.com
Authorization: Bearer ppk_k3nmw2x7q4tz_8lV0m1Q2…
  • O cheie are forma ppk_<id cheie>_<secret>. Id-ul cheii (12 caractere) este public: apare în listele de chei și în jurnalul de audit. Secretul este afișat o singură dată, la creare sau la rotație. PlusPanel păstrează doar un hash al cheii și nu o mai poate afișa.
  • O cerere cu antetul Authorization ignoră complet cookie-urile: fără sesiune, fără token CSRF.
  • O cheie malformată, necunoscută, expirată sau revocată primește 401 cu codul invalid_api_key și WWW-Authenticate: Bearer error="invalid_token".
  • GET /api/v1/auth/me îți spune în numele cui acționează cheia, cu ce roluri și permisiuni.

Scope-urile provin din aceleași roluri și permisiuni ca în panou; nu există un al doilea sistem de permisiuni. Fiecare permisiune aparține unei resurse și este fie de citire, fie de scriere:

Scope Permite
<resursă>:read Citirea resursei, de exemplu servers:read, accounts:read
<resursă>:write Modificarea ei (și citirea: write include read), de exemplu sites:write
*:read Citirea tuturor resurselor
* Tot ce are voie utilizatorul (nu există *:write: se scrie *)

Resursele sunt accounts, alerts, apikeys, audit, backups, databases, dns, jobs, mail, observability, plans, runtime, security, servers, sftp, sites, storage, tenant, updates, users, waitlist și webhooks; GET /api/v1/api-keys/scopes le listează împreună cu permisiunile acoperite de fiecare scope, iar panoul arată aceeași listă când creezi o cheie. La cererile GET, scope-ul read al unei resurse acoperă și citirile pe care panoul le protejează cu o permisiune de administrare (de exemplu lista site-urilor), cu excepția câtorva citiri stricte care întorc un secret sau datele însele: rezultatul unic al unui job, conținutul fișierelor și terminalul web (accounts), linkurile de invitație (users), restaurările și descărcările de backup (backups) și probele de test din laborator (jobs) cer scope-ul write al resursei.

O cheie nu poate face niciodată mai mult decât utilizatorul ei. O cerere făcută cu o cheie este permisă doar dacă sunt adevărate amândouă:

  1. rolul utilizatorului (și, pentru reselleri și clienți, conturile la care au acces) o permite, exact ca în panou, și
  2. unul dintre scope-urile cheii acoperă permisiunea.

Dacă utilizatorul pierde un rol, îl pierd și cheile lui. Câteva acțiuni de self-service nu sunt disponibile niciodată cu o cheie, oricare i-ar fi scope-urile: schimbarea parolei sau a unui factor de autentificare, gestionarea sesiunilor, step-up, impersonarea și aprobarea unei autentificări din CLI. GET /auth/me, GET /tenant/edition și GET /api-keys/scopes merg cu orice cheie.

O cheie căreia îi lipsește un scope primește 403 insufficient_scope (mesajul numește scope-ul necesar); un endpoint care cere o sesiune autentificată răspunde 403 api_key_not_allowed.

  • O cheie personală acționează în numele tău. Nu mai funcționează după ce utilizatorul tău este dezactivat sau șters.
  • O cheie de organizație acționează ca un utilizator de serviciu dedicat al organizației (rol admin, fără parolă, nu se poate autentifica în panou). Supraviețuiește oamenilor care au creat-o și este administrată de adminii organizației (crearea ei cere permisiunea apikeys.manage la nivelul organizației). Folosește-o pentru integrări care trebuie să meargă și când se schimbă echipa. O cheie de organizație poate crea doar chei de organizație.

Cheile create de autentificarea în browser a CLI-ului sunt chei personale (sursa device, valabile implicit 90 de zile; vezi mai jos).

  • Expirarea este opțională și se stabilește la crearea cheii (nu mai poate fi schimbată). O cheie expirată primește 401 invalid_api_key.
  • Rotația (POST /api-keys/{id}/rotate) dă cheii un secret nou și îi păstrează id-ul, scope-urile și setările. Cu grace_seconds (cel mult 86400) vechiul secret rămâne valid o perioadă de grație, cât timp îl distribui pe cel nou. O cheie personală poate fi rotită doar de proprietarul ei.
  • Revocarea este imediată și definitivă.
  • Panoul arată pentru fiecare cheie ultima utilizare (ora și adresa IP) și numărul zilnic de cereri.

O cheie poate fi limitată la o listă de rețele (CIDR-uri sau adrese individuale, IPv4 și IPv6; un CIDR cu biți de gazdă setați, ca 192.0.2.7/24, este refuzat). O cerere de la orice altă adresă primește 403 api_key_ip_denied, chiar și cu o cheie validă.

O cheie poate crea sau modifica chei doar cu scope-ul apikeys:write și doar cu scope-uri, expirare, listă de IP-uri și limită de rată cel mult la fel de largi ca ale ei (altfel 403 api_key_wider_than_caller). Fiecare creare, rotație, revocare, modificare și refuz este înregistrată în jurnalul de audit.

pluspanel login din CLI își obține cheia printr-o autentificare în browser de forma RFC 8628; și alte unelte pot folosi aceleași două endpointuri publice (fără credențiale, fără Idempotency-Key):

  1. POST /api/v1/auth/device/code cu {"client_name": "…"} răspunde cu un device_code secret, un user_code (XXXX-XXXX), pagina /device a panoului ca verification_uri (și verification_uri_complete cu tot cu cod), expires_in (600 de secunde) și interval (5 secunde). Cel mult 10 coduri pe minut și 5 cereri în așteptare per adresă (429 rate_limited).
  2. Afișează user_code și deschide pagina. Persoana se autentifică normal, verifică cererea (nume, adresă, oră) și o aprobă (confirmându-și din nou identitatea dacă nu a făcut-o în ultimele 5 minute) sau o refuză.
  3. Interoghează POST /api/v1/auth/device/token cu {"device_code": "…"} la fiecare interval secunde. Până la decizie răspunsul este 400 cu codul authorization_pending; slow_down înseamnă că ai interogat prea des (adaugă 5 secunde la interval); access_denied și expired_token (după 10 minute, pentru un cod necunoscut sau după ce cheia a fost predată) încheie fluxul. Sunt documente problem: eroarea RFC 8628 se citește din code.
  4. Prima interogare după aprobare răspunde 200 cu token (afișat o singură dată), key, tenant și user: o cheie personală numită CLI: <client_name>, cu acces complet sau doar de citire, după cum a fost aprobată.
Terminal window
curl -fsS -X POST "$PLUSPANEL_URL/api/v1/auth/device/code" \
-H "Content-Type: application/json" -d '{"client_name": "deploy tool on laptop"}'
# {"device_code":"…","user_code":"BCDF-GHJK","verification_uri":"https://panel.example.com/device",
# "verification_uri_complete":"https://panel.example.com/device?code=BCDF-GHJK","expires_in":600,"interval":5}
curl -sS -X POST "$PLUSPANEL_URL/api/v1/auth/device/token" \
-H "Content-Type: application/json" -d '{"device_code": "…"}'
# înainte de decizie: 400 {"code":"authorization_pending", …}
# după aprobare: 200 {"token":"ppk_…","key":{…},"tenant":{"slug":…,"name":…},"user":{…}}

Fiecare cheie are un buget de cereri pe minut (implicit 600, în toate edițiile; unei chei i se poate da o limită mai mică). Vezi Convenții → Limite de rată.

  • O cheie pentru fiecare integrare, cu cele mai înguste scope-uri de care are nevoie și cu o dată de expirare.
  • Păstrează cheile într-un seif de secrete sau într-o variabilă de mediu, niciodată în codul sursă.
  • Pentru integrări de durată preferă o cheie de organizație, iar pentru servere cu adrese fixe o listă de IP-uri permise.
  • Rotește cheile periodic și imediat dacă una ar fi putut fi expusă; revocă cheile pe care nu le mai folosești.