Ghid și perspectivă

Partener API Authorization Teste pentru AI API Portaluri pentru distribuitori

Un plan de testare practic pentru prevenirea accesului între chiriași în API-urile Partner care creează clienți, emit chei, adaugă credite, exportă utilizarea și blochează accesul.

Un partener API pentru portalurile de distribuitori trebuie să presupună că fiecare ID de obiect dintr-o solicitare poate fi copiat, ghicit, reluat, înregistrat de o altă integrare sau transmis prin instrumentul personal greșit. Problema de bază nu este dacă ID-urile clienților sunt opace. Problema este dacă fiecare acțiune demonstrează că apelantul, contul partenerului, chiriașul țintă, obiectul, proprietatea și starea de aprobare aparțin împreună.

Acest lucru contează cel mai mult într-un portal de reseller AI API, deoarece API expune, de obicei, obiecte din planul de control cu impact mare: clienți din aval, chei API virtuale, portofele, ajustări de credit, exporturi de utilizare, destinații webhook, utilizatori ai personalului și blocări de urgență. O singură verificare de autorizare lipsă poate permite unui client să citească utilizarea unui alt client, să permită unui simbol personal să mute credite între chiriași sau să permită un simbol de automatizare să revoce o cheie pe care nu ar trebui să o vadă niciodată.

Realitate: OWASP API Security 2023 listează Nivelul obiectului spart Authorization ca API1 și Nivelul proprietății obiectului spart Authorization ca API3. În termeni practici, verificările la nivel de obiect răspund „poate acest apelant să acționeze asupra acestui obiect?” în timp ce verificările la nivel de proprietate răspund „poate acest apelant să seteze sau să citească acest câmp?” Ambele sunt preocupări de primă clasă pentru designul partenerului API.

Definiți contractul Authorization înainte de a scrie teste

Authorization testele sunt utile numai dacă testează în raport cu un contract de politică explicit. Începeți cu o matrice care descrie ce actor poate face ce acțiune pe ce țintă, în ce condiții. Nu vă bazați pe numele punctelor finale sau pe rolurile UI ca politică.

O matrice utilă are aceste coloane:

  • Tip de actor: proprietar de partener, administrator de partener, operator financiar, operator de asistență, indicativ de automatizare, administrator de clienți, utilizator de doar citire pentru clienți.
  • Contul de partener: contul de distribuitor sau de agenție care deține relația cu clienții din aval.
  • Chiriaș țintă: contul de client din aval care este creat, facturat, inspectat, suspendat sau șters.
  • Tip de obiect: client, cheie virtuală, portofel, înregistrare în registru, raport de utilizare, punct final webhook, utilizator personal, profil de prețuri, mapare furnizor.
  • Acțiune: creați, citiți, listați, actualizați, revocați, completați, rambursați, exportați, înghețați, dezghețați.
  • Autoritate monetară: dacă acțiunea modifică soldul, limita de credit, marja, starea decontării, starea facturii sau limitele de cheltuieli.
  • Starea de aprobare: dacă cererea este preaprobată, în așteptare de aprobare, aprobată dublă, expirată sau doar pentru urgențe.

De exemplu, unui operator de asistență i se poate permite să vadă metadatele cheii mascate ale unui client și să înghețe o cheie în timpul unui incident, dar să nu creeze credite, să modifice catalogul de prețuri, să exporte datele complete de utilizare sau să deblocheze cheia fără aprobare. Un operator financiar poate crea o ajustare de credit pentru un client deținut de același partener, dar numai în limita unei sume configurate și numai după ce există o înregistrare de aprobare.

Recomandare: scrieți matricea ca artefact cu versiune, apoi faceți ca fiecare nume de testare de autorizare să facă referire la un rând sau o regulă. Când o politică se modifică, diferența ar trebui să arate atât modificarea contractului, cât și modificarea testului.

Utilizați referințe la obiecte legate de locatari

ID-urile opace reduc riscul de enumerare, dar nu dovedesc autorizarea. Un ID de cheie virtuală, un ID de portofel, un ID de intrare în registru, un ID de export de utilizare sau un simbol cursor trebuie rezolvat în limitele așteptate ale partenerului și chiriașului.

Un model de căutare sigur este:

resolve object where
  object.id = request.object_id
  and object.partner_id = actor.partner_id
  and object.customer_id = request.customer_id
  and actor has action_scope for object_type/action
  and object.state allows action

Modelul periculos este:

object = find_by_id(request.object_id)
if actor.has_scope("keys:revoke"):
  revoke(object)

A doua versiune autorizează posesia unui domeniu, nu autoritate asupra țintei. Eșuează atunci când un simbol valid pentru Partenerul A trimite un ID de cheie de la Partenerul B sau când un operator pentru Clientul A trimite un ID de portofel de la Clientul B.

Legarea chiriașilor ar trebui să acopere mai mult decât obiectele evidente. Includeți indicative de cursor pentru rapoartele de utilizare, ID-uri de export de job, ID-uri de punct final webhook, ID-uri de aprobare, chei de idempotity și ID-uri de ajustare a registrului. Aceste obiecte se simt adesea „interne”, tocmai de aceea devin puncte slabe.

Construiți un dispozitiv minim de testare între chiriași

Folosiți un dispozitiv în mod deliberat mic, care face accesul greșit ușor de exprimat. Scopul nu este un volum mare de date. Scopul este separarea clară.

Partner P1
  Staff: p1_owner, p1_support, p1_finance
  Token: p1_full_token, p1_support_token, p1_finance_token
  Customer C1A
    Key K1A
    Wallet W1A
    Usage cursor U1A
    Ledger entry L1A
  Customer C1B
    Key K1B
    Wallet W1B
    Usage cursor U1B
    Ledger entry L1B

Partner P2
  Staff: p2_owner
  Token: p2_full_token
  Customer C2A
    Key K2A
    Wallet W2A
    Usage cursor U2A
    Ledger entry L2A

Acest dispozitiv vă permite să testați două clase de eșec. În primul rând, acces încrucișat de același partener, în care un apelant de la P1 încearcă să atingă C1B în timp ce acționează pe C1A. În al doilea rând, accesul între parteneri, în care un jeton P1 încearcă să atingă obiectele lui P2.

Recomandare: rulați același dispozitiv împotriva partenerului public API și backend-ului portalului de distribuitori. Restricțiile UI nu protejează API clienți direcți, joburile de fundal, instrumentele de dezvoltare ale browserului sau indicativele de integrare compromise.

Testați la nivel de obiect Authorization pe fiecare punct final cu impact mare

Pentru fiecare punct final care acceptă un ID de obiect, creați cel puțin un test pozitiv și mai multe teste negative. Testele pozitive demonstrează că dispozitivul este valabil. Testele negative dovedesc că limitele sunt valabile.

Crearea și căutarea clienților

Crearea clienților pare de obicei inofensivă, deoarece chiriașul țintă nu există încă. Încă are nevoie de autorizare, deoarece apelantul poate încerca să creeze clienți cu un alt partener, să atribuie un profil de preț interzis sau să stabilească metadate interne.

Test cases:

  • Un proprietar de partener poate crea un client sub același partener.
  • Un simbol de automatizare cu sfera de aprovizionare pentru clienți poate crea un client sub același partener.
  • Un simbol numai de asistență nu poate crea un client.
  • Un simbol P1 nu poate crea un client cu partner_id=P2.
  • Un indicativ la nivel de client nu poate enumera clienții frați.

Crearea, revocarea și rotația cheilor

Acțiunile cheie ale ciclului de viață au un impact mare, deoarece acordă acces la timpul de execuție și pot întrerupe sarcinile de lucru de producție. Planurile de control ale furnizorului expun de obicei obiecte administrative, cum ar fi proiecte, spații de lucru, conturi de servicii, membri și chei API prin intermediul API-urilor. Un gateway sau un strat de reseller ar trebui să-și trateze propriile chei virtuale cu aceeași grijă.

Test cases:

  • Automatizarea P1 poate crea K1A numai pentru C1A atunci când indicativul său include domeniul de scriere a cheii.
  • Asistența P1 nu poate crea K1A dacă rolul de asistență este doar în citire pentru chei.
  • Asistența P1 poate îngheța K1A numai dacă înghețarea de urgență este în domeniu.
  • Asistența P1 nu poate revoca K1B când contextul solicitării spune C1A.
  • Jetonul complet P1 nu poate revoca K2A.
  • Un administrator de client pentru C1A nu poate roti, dezvălui sau revoca K1B.

Pentru echipele care implementează automatizarea Partenerului API, testul important nu este doar „care acest simbol are scriere la cheie?” Este „Acest simbol are scrierea cheii pentru acest partener, acest client, această cheie, această stare și această operație?”

Încărcări de credite și modificări ale portofelului

Acțiunile de mutare a banilor necesită teste mai stricte decât actualizările obișnuite. O reîncărcare a creditului poate fi corectă din punct de vedere sintactic și poate fi totuși neautorizată, deoarece portofelul aparține altui chiriaș, suma depășește autoritatea, înregistrarea de aprobare vizează un alt client sau cheia de idempotnță a fost folosită pentru o operațiune diferită.

Cazuri de testare:

  • Finanțarea P1 poate completa W1A în limita sumei sale după aprobare.
  • Finanțele P1 nu pot completa W1B folosind o aprobare creată pentru W1A.
  • Finanțele P1 nu pot completa W2A.
  • Asistența P1 nu poate încărca niciun portofel.
  • Un jeton de automatizare nu poate modifica limita de credit decât dacă are un domeniu de aplicare explicit pentru mișcarea banilor.
  • O cheie de idempotnță reluată nu poate redirecționa o încărcare anterioară W1A către W1B.

Recomandare: tratați cheile de idempotity ca fiind aplicate pentru partener plus operațiune plus chiriașul țintă plus corpul de solicitare normalizat. O reîncercare ar trebui să fie sigură, dar nu ar trebui să devină un canal de coliziune între locatari.

Rapoarte de utilizare și cursoare de export

Rapoartele de utilizare sunt ușor de subprotejat deoarece sunt doar pentru citire. În sistemele de reseller, datele de utilizare pot dezvălui numele clienților, sarcinile de lucru, alegerile de model, costurile, identificatorii utilizatorilor finali și marjele comerciale. Cursor jetoane și ID-uri de export trebuie să fie și ele legate de locatari.

Cazuri de testare:

  • Administratorul C1A poate citi segmentele de utilizare C1A.
  • Administratorul C1A nu poate citi utilizarea C1B schimbând customer_id.
  • Jetonul de analiză P1 numai pentru citire poate exporta utilizarea pentru clienții P1 numai dacă este prezent domeniul de export.
  • Jetonul P1 nu poate relua un export de utilizare P2 cu un cursor copiat.
  • Un cursor creat pentru un raport la nivel de cheie nu poate fi reutilizat pentru a prelua utilizarea la nivel de chiriaș decât dacă este permis în mod explicit.

Dacă portalul expune AI API măsurarea utilizării clienților, testați atât vizualizările rezumate, cât și exporturile descărcabile. Căile de export ocolesc adesea același controler sau cod de politică folosit de paginile interactive.

Testați la nivel de proprietate Authorization pe punctele finale PATCH și actualizați

Nivelul proprietății obiectului spart Authorization apare atunci când unui apelant i se permite să actualizeze un obiect, dar poate seta și câmpuri care ar trebui să fie interne, privilegiate sau deținute de un alt flux de lucru.

Pentru API-urile Partner, câmpurile sensibile includ adesea:

    Câmpurile
  • partner_id, customer_id și proprietatea părinte.
  • provider_project_id, provider_workspace_id și referințe cheie din amonte.
  • pricing_catalog_version, margin_tier și anulări de reduceri.
  • wallet_balance, credit_limit, settlement_status și starea facturii.
  • fraud_status, risk_score și semnalizatoare de conformitate.
  • role, scopes și semnalizări de ocolire a aprobării.

Folosiți liste permise, nu liste refuzate. De exemplu, un punct final de actualizare a profilului clientului poate permite display_name, billing_email și metadata.external_reference. Ar trebui să respingă sau să ignore margin_tier, credit_limit și provider_project_id, chiar dacă apelantul poate actualiza obiectul client.

PATCH /partner/customers/C1A
{
  "display_name": "Acme Support Team",
  "margin_tier": "internal_zero_margin",
  "provider_project_id": "provider-project-owned-by-C1B"
}

Rezultatul așteptat ar trebui să fie determinist. Preferați o eroare de validare care identifică câmpurile interzise fără a dezvălui valorile interne sensibile. Nu acceptați în tăcere câmpuri privilegiate și apoi ignorați-le, cu excepția cazului în care contractul dvs. API utilizează deja acel model în mod constant.

Faceți ca respingerea să nu fie enumerate

Testurile negative ar trebui să verifice atât codurile de stare, cât și forma răspunsului. Dacă un jeton P1 solicită K2A, răspunsul nu ar trebui să arate dacă K2A există sub alt partener.

O regulă comună este:

  • Folosiți 401 când apelantul nu este autentificat.
  • Folosiți 403 când apelantul este autentificat, dar nu are un domeniu de acțiune în propria limită.
  • Folosiți 404 sau un răspuns generic negăsit atunci când obiectul se află în afara limitei apelantului și existența nu ar trebui să fie dezvăluită.

Convenția exactă poate varia, dar comportamentul trebuie să fie consecvent. Organismul de refuz ar trebui să evite mesaje precum „cheia aparține altui client” sau „portofelul există sub partenerul P2”. Aceste informații sunt utile atacatorilor și rareori utile clienților legitimi.

Compartiment: refuzurile generice fac depanarea mai dificilă pentru dezvoltatorii parteneri. Rezolvați asta cu ID-uri de solicitare, jurnale de audit structurate și instrumente de asistență, nu prin scurgerea existenței între locatari în erori publice API.

Înregistrați decizia Authorization, încărcături utile nu sensibile

Testele

Authorization ar trebui să afirme, de asemenea, că negările produc dovezi interne utile. Aveți nevoie de suficiente detalii pentru a reconstrui ceea ce s-a întâmplat în timpul unui incident fără a stoca solicitări brute, secrete sau date inutile despre clienți.

Câmpurile de jurnal ar trebui să includă:

  • request_id și ID-ul corelației de urmărire.
  • actor_id, tipul actorului, ID-ul simbolului și șablonul de rol.
  • partner_id de la actorul autentificat.
  • Chiriaș țintă solicitat și chiriaș țintă rezolvat, când rezoluția este permisă.
  • Tipul de obiect și acțiune.
  • Versiunea politicii și rezultatul deciziei.
  • Codul motiv al respingerii, cum ar fi missing_scope, tenant_mismatch, approval_required sau field_not_allowed.

Nu înregistrați cheile API complete, secretele furnizorului din amonte, solicitările, încărcăturile utile de utilizare brută sau conținutul de export complet. Pentru cererile refuzate între chiriași, aveți grijă ca jurnalele interne să fie controlate prin acces; răspunsul public poate fi generic în timp ce echipa de securitate are încă suficiente dovezi.

Automatizarea cablajului în CI și punere în scenă

Cablajul de testare ar trebui să se desfășoare în trei locuri: teste unitare pentru funcțiile de politică, teste de integrare pentru API puncte finale și probe de punere în pas pe backend-ul portalului de distribuitor implementat. Each layer catches different failures.

A practical CI structure:

authz-tests/
  fixtures/
    partners.json
    customers.json
    roles.json
    tokens.json
  matrix/
    keys.yaml
    wallets.yaml
    usage_exports.yaml
    customers.yaml
  tests/
    test_keys_authz.ts
    test_wallet_authz.ts
    test_usage_authz.ts
    test_patch_allowlists.ts

Fiecare rând de matrice ar trebui să definească actorul, cererea, decizia așteptată și comportamentul neenumerator așteptat.

- name: p1_support_cannot_revoke_p2_key
  actor: p1_support_token
  method: POST
  path: /partner/customers/C2A/keys/K2A/revoke
  expected_status: 404
  expected_error_code: not_found
  expected_audit_reason: tenant_mismatch

Adăugați variante de tip mutație care schimbă câte un identificator la un moment dat: ID-ul clientului, ID-ul cheii, ID-ul portofelului, ID-ul de aprobare, cursorul, cheia de idempotency și ID-ul punctului final webhook. These tests are repetitive by design. Repetarea este acceptabilă atunci când demonstrează că fiecare identificator are un scop independent.

Operational Checklist

Înainte de a expedia un punct final Partener API, utilizați această listă de verificare:

  • Punctul final are o regulă de autorizare numită în matricea de politici.
  • Fiecare căutare de obiecte include condiții de limită pentru partener și chiriaș.
  • Fiecare punct final al listei filtrează după limita actorului înainte de paginare.
  • Fiecare cursor, ID de export, ID de webhook, ID de aprobare și cheie de idempotnță sunt acoperite.
  • Punctele finale PATCH folosesc liste de proprietate permise în funcție de rol și acțiune.
  • Acțiunile de mutare a banilor necesită un domeniu de aplicare explicit și o stare de aprobare.
  • Înghețarea de urgență este separată de dezghețare și de autoritatea de credit.
  • Negăturile evită scurgerile de existență între chiriași.
  • Jurnalele de audit înregistrează decizia de autorizare și versiunea politicii.
  • Aceleași teste negative rulează împotriva căilor de backend API și portalului.

Trade-Offs to Decide Explicitly

Lunetele cu granulație fină reduc raza exploziei, dar măresc complexitatea integrării partenerilor. Șabloanele de rol implicite ajută: proprietar, finanțe, asistență, analiză, automatizare aprovizionare și răspuns în caz de urgență. Permiteți partenerilor avansați să personalizeze din acele șabloane în loc să înceapă de la domenii brute.

Listele stricte de proprietate permisă încetinesc lansarea funcțiilor, deoarece fiecare câmp editabil nou necesită o modificare a politicii. Această frecare este utilă pentru facturare, prețuri, maparea furnizorilor și domeniile de gestionare a cheilor. Pentru câmpurile cu profil cu risc scăzut, procesul poate fi mai ușor.

Fluxurile de aprobare reduc modificările accidentale sau rău intenționate de credit, dar adaugă latență operațiunilor de asistență legitime. Păstrați înghețarea de urgență rapidă, reversibilă și controlată separat. Nu lăsați același simbol de urgență să adauge credite, să modifice marjele, să exporte utilizarea și să deblocheze conturile.

Predicție: portalurile de distribuitori vor continua să expună mai multe acțiuni administrative prin intermediul API-urilor Partner, deoarece clienții se așteaptă la furnizarea, raportarea și automatizarea cu autoservire. Sistemele care îmbătrânesc bine vor fi cele cu contracte de autorizare și teste negative, nu cele care se bazează numai pe denumirea rutelor, controale ascunse ale interfeței de utilizare sau ID-uri opace.

Actionable Conclusion

Construiți cablajul de autorizare înainte ca Partenerul API să devină suficient de mare încât fiecare punct final să aibă propria excepție. Începeți cu doi parteneri, doi clienți sub un partener, un client sub alt partener și un set mic de jetoane. Apoi testați acțiunile care vă pot afecta cel mai mult: crearea cheii, revocarea cheii, reîncărcările de credit, exporturile de utilizare, actualizările portofelului, reutilizarea aprobării, reluarea idempotității și câmpurile PATCH.

Contractul este simplu de declarat: un apelant trebuie să aibă domeniul de aplicare potrivit, sub partenerul potrivit, pentru chiriașul, obiectul, proprietatea, acțiunea, suma și starea de aprobare potrivite. Lucrările de implementare fac acest lucru adevărat pentru fiecare punct final, inclusiv pentru cele plictisitoare.

Lectură asociată

FAQ

Întrebări frecvente

Sunt ID-urile opace suficiente pentru a împiedica accesul partenerului API între chiriași?
Nu. ID-urile opace reduc riscul de ghicire și enumerare, dar fiecare cerere necesită încă o verificare a autorizației care leagă actorul, partenerul, chiriașul, obiectul, acțiunea și starea.
Testele de autorizare ar trebui să ruleze numai împotriva publicului API?
Nu. Rulați-le împotriva partenerului public API și backend-ului portalului de distribuitori. Verificările UI nu protejează API clienții direcți, lucrătorii de fundal, jetoanele compromise sau rutele backend alternative.
Care puncte finale ale partenerilor API necesită mai întâi teste de autorizare negative?
Începeți cu puncte finale cu impact mare: crearea clienților, crearea și revocarea cheilor, reîncărcări de portofel, limite de credit, exporturi de utilizare, înregistrări de aprobare, chei de idempotnță, destinații webhook și puncte finale PATCH pentru clienți sau obiecte de facturare.
Cum ar trebui să răspundă API-urile atunci când un token face referire la obiectul altui chiriaș?
Folosiți o convenție de răspuns fără enumerare. Multe API-uri returnează un răspuns generic negăsit atunci când obiectul se află în afara graniței apelantului, înregistrând în același timp motivul exact al respingerii în jurnalele de audit intern.