În primăvara lui 2026, două companii au căzut victime aceleiași clase de atac: credențiale furate, chei API străine și consum masiv de Gemini pe factura lor. Primul incident s-a încheiat cu o factură de jumătate de milion de euro. Al doilea, două luni mai târziu, a lovit un mediu aflat deja sub monitorizarea noastră și a fost oprit în câteva ore. Acest text povestește ce am construit între cele două date și de ce partea cea mai grea nu a fost detectarea anomaliilor, ci decizia când trebuie într-adevăr să alertăm.
Jumătate de milion de euro în trei zile
Mai 2026. Un mare grup tehnologic, care operează printre altele platforme de e-commerce și streaming, folosește Google Cloud simbolic. Infrastructura principală se află în altă parte; pe GCP rulează doar sisteme secundare, care generează aproximativ 500 de dolari pe lună.
La mijlocul lunii, compania co-organizează un mare eveniment tehnologic, intens promovat. Întreaga echipă de ingineri este la fața locului, cu mâinile pline. Exact în acele zile, cineva pune mâna pe cheia scursă a unui cont de serviciu vechi, apoi își ridică într-unul dintre proiecte permisiunile la rolul Editor, activează Vertex AI și pornește inferența pe modelul Gemini 1.5 Pro. Nu de test. La scară industrială.
Rezultatul? Factura pentru consumul de resurse GCP în perioada 14–16 mai ajunge la 500 960 de euro. O mie de bugete lunare ale acestei companii, arse în trei zile.
Partea cea mai amară a acestei povești este că alertele au funcționat formal. Google a trimis o notificare privind suspiciunea de abuz și depășirea cheltuielilor medii încă din 14 mai. Numai că prima alertă de buget, la o medie de 500 de dolari, indica o sumă care în valori absolute părea inofensivă. Iar oamenii care ar fi trebuit să o citească se aflau chiar atunci pe scenă.
Reacția completă a pornit pe 17 mai și a fost exemplară: conturi dezactivate, legăturile IAM malițioase eliminate, proiectul înghețat în mod read-only pentru analiza criminalistică, politici de securitate noi în întreaga organizație. Ancheta a confirmat că datele nu au fost exfiltrate, iar pagubele s-au limitat la un singur proiect. Dar contorul apucase deja să se oprească la jumătate de milion de euro.
O zi obișnuită pe acest cont costă aproximativ zece-douăzeci de euro, așa că la această scară, astfel de bare sunt pur și simplu invizibile. Aceasta nu este o captură de ecran dintr-o consolă reală.
Datele diagramei (tabel)
| Ziua | tipică | 14 mai | 15 mai | 16 mai |
|---|---|---|---|---|
| Cost | ≈ 16 € | ≈ 292 000 € | ≈ 168 000 € | ≈ 41 000 € |
Observarea acestui caz ne-a permis să definim trei probleme-cheie, care au intrat direct în backlogul nostru:
- Alertele statice de buget sunt oarbe în mediile cu cheltuieli mici, pentru că o creștere procentual gigantică arată la început ca niște sume neînsemnate.
- Notificările despre abuzuri sunt trimise exclusiv proprietarului mediului. Cu setările standard, partenerul de facturare nu vede nimic din toate acestea până când clientul nu îl contactează singur.
- În acest caz nu exista niciun siguranță automată care să fi sugrumat acel consum.
Am decis ca, la clienții noștri, astfel de incidente să fie observate mai întâi de noi, nu de factură. Așa a apărut Cloud Cost Sentinel.
Costul este un semnal de securitate
Industria are deja un nume pentru asta: LLMjacking. Credențialele cloud furate nu servesc la exfiltrarea datelor, ci la consumul masiv al unor API-uri scumpe de modele lingvistice, adesea revândut mai departe. Factura rămâne la victimă. Cazurile documentate public înseamnă sume de la câteva mii la zeci de mii de dolari la dezvoltatori individuali și echipe mici. Companiile descrise aici nu au fost excepții, ci doar următoarele poziții într-un mecanism bine uns.
De aceea, la FOTC tratăm telemetria de facturare așa cum SecOps tratează logurile: ca un flux de evenimente analizat continuu. O creștere bruscă a costului are aproape întotdeauna o cauză tehnică, iar o bună parte dintre aceste cauze sunt incidente:
Pragurile de buget nu prind așa ceva, pentru că „normalitatea” fiecărui cont e diferită. O sumă care la un client înseamnă o marți obișnuită, la altul este bugetul pe trei luni. Baseline-ul trebuie să fie comportamental și calculat separat pentru fiecare cont.
Arhitectura: de la exportul de facturare la PagerDuty
Operăm sute de conturi de facturare Google Cloud. Fiecare are un export complet de facturare într-un tabel BigQuery partiționat. De altfel, acesta este singurul lucru pe care sistemul îl cere de la un mediu. Pe această fundație rulează detectorul: un serviciu ușor, fără stare, pe Cloud Run, trezit de un planificator în cicluri scurte și regulate.
Date
Detecție
Decizie
Reacție
Toate componentele sunt fără stare. Singura stare a sistemului este istoricul detecțiilor, scris înapoi în BigQuery. El alimentează dashboardul și deciziile de realertare. Alertele ajung și la noi, nu doar la client.
Patru întrebări pe care le punem datelor în fiecare ciclu de analiză
Fiecare tip de anomalie este o altă întrebare, cu o altă fereastră de referință. Numitorul comun aici este că fiecare cont este comparat exclusiv cu propriul istoric. Pragurile concrete, lungimile ferestrelor și plafoanele valorice sunt parametri de configurare aleși per implementare, motiv pentru care nu îi detaliem aici cifră cu cifră.
| Detector | Întrebare | Punct de referință |
|---|---|---|
| Zilnic (z-score) | Costul de ieri sau de azi se abate de la normă? | Fereastră glisantă a ultimelor zile, excluzând ziua curentă; alarmă la o abatere semnificativă statistic, peste un plafon valoric |
| Spike orar | Este această oră drastic mai scumpă decât de obicei? | Profilul orar al contului din ultimele zile; alarmă la un multiplu al costului tipic pentru ora respectivă |
| Cont nou | Un cont proaspăt creat cheltuiește mult instantaneu? | Cont fără istoric, care generează imediat cheltuieli mari; unul dintre cele mai puternice semnale de abuz |
| Prognoză lunară | Încotro se îndreaptă această lună? | Extrapolare la începutul lunii comparativ cu lunile precedente; alarmă când prognoza scapă clar de sub control |
Inima detectorului zilnic este o singură interogare pe ferestre în BigQuery și tocmai această parte a implementării este cea mai simplă. Adevărata complexitate se ascunde în detalii: ziua curentă rămâne intenționat în afara baseline-ului (De ce? Se va vedea imediat…), ferestrele și pragurile trebuie calibrate pe date reale, iar în date nu ai voie să te încrezi orbește, nici în completitudinea, nici în structura lor. Sună a mărunțișuri, dar fiecare dintre ele ne-a ars cândva.
Iulie: aceeași clasă de atac, alt final
La două luni după incidentul din mai, același scenariu de atac a lovit un client de-al nostru, un mic studio de aplicații mobile. Mediul acesta era deja sub monitorizarea Cloud Cost Sentinel. Începutul a fost banal: unul dintre dezvoltatori a vrut să instaleze un tool popular și a dat clic pe un rezultat sponsorizat. Site-ul arăta cum trebuie, installerul la fel. Înăuntru stătea un stealer dintr-o campanie documentată public, printre alții, de Bitdefender și Trend Micro. Deși contul avea MFA activat, nu a contat deloc, pentru că acest tip de malware operează din interiorul unui calculator deja autentificat. Fură o sesiune care are autentificarea de mult în urmă.
În seara zilei de 4 iulie, cu credențialele furate s-a conectat un script de pe un server de hosting din Germania. După ani de colaborare pe Firebase, contul avea rolul Editor în peste zece proiecte, ceea ce în Google Cloud înseamnă, printre altele, dreptul de a activa API-uri și de a crea chei. Automatul a avut nevoie de 3 minute și 16 secunde ca să treacă prin proiecte și să lase în urmă 16 API-uri activate, 9 conturi de serviciu și 28 de chei. Apoi, timp de douăsprezece zile, s-a lăsat liniștea. Cheile stăteau și așteptau.
Pe 16 iulie, la 13:45, cheile au prins viață și consumul masiv de Gemini a pornit în toate proiectele deodată. La 4:30 dimineața, imediat ce primele date ale zilei au ajuns în exportul de facturare, detectorul a dat alarma. Cardul CRITICAL arăta astfel: un z-score mult peste cinci sute, o creștere măsurată în zeci de mii de procente, iar în defalcarea pe servicii practic întreaga creștere provenea dintr-o singură poziție: Gemini API, un serviciu nefolosit vreodată pe acest cont. Escaladarea a plecat.
Acest client nu folosea suportul nostru permanent și nu ne acordase permisiuni asupra mediului său, așa că rolul nostru se încheia la alarmă și escaladare. Doar el putea bloca abuzul. Echipa clientului a preluat subiectul la începutul zilei: pe la 08:20 traficul revenise la baseline, iar până la 12:40 cheile și conturile de serviciu străine dispăruseră din toate proiectele.
Baseline-ul acestui cont este de aproximativ 20 de dolari pe zi. O singură zi de abuz activ a fost suficientă pentru a depăși de mai multe ori cheltuielile totale ale contului pe un an întreg. Aceasta nu este o captură de ecran din consola clientului.
Datele diagramei (tabel)
| Ziua | tipică | 16 iulie | 17 iulie |
|---|---|---|---|
| Cost | ≈ $20 | ≈ $33 250 | ≈ $650 |
Când exportul a completat ziua, contorul s-a oprit la treizeci și trei de mii de dolari, iar deviația a crescut la 842 de sigma. Ziua s-a închis de 906 ori peste norma contului. Pe axa timpului arată așa: consumul a pornit după 13:45, alarma a plecat la 4:30, pentru că atât a durat ca datele să ajungă în exportul de facturare, iar tot restul a fost timp de reacție de partea clientului. Era vineri. Povestea din mai arată destul de precis ce s-ar fi întâmplat dacă acel consum ar fi lucrat liniștit tot weekendul. Acolo unde avem nu doar mandat de escaladare, ci și permisiuni de reacție, acele câteva ore se pot restrânge la câteva minute.
O alertă care s-a stins singură
În a doua zi a incidentului din iulie, contul încă ardea 14,2 mii de dolari pe zi. Iar z-score-ul nostru pentru acea zi a fost… 1,1. Statistic? Nimic interesant, vă rugăm să vă dispersați.
Motivul: fereastra glisantă avusese timp să absoarbă ziua de vârf în propriul baseline. Media mobilă a sărit de la 20 de dolari la mii, deviația standard a explodat, iar incidentul în curs a început să pară noua normalitate. Alerta critică se degrada la o avertizare, deși cheltuielile nu scăzuseră nici măcar cu un cent.
Prima corecție a fost statistică: excluderea zilelor anormale din baseline, calculându-l în două treceri. Nu a funcționat. A doua zi a incidentului avea deja un z-score subevaluat, așa că nu a primit eticheta de outlier (valoare extremă), iar din a treia zi a otrăvit din nou fereastra. Doar după ce am revenit asupra modificării, am înțeles că nu luptăm cu adversarul potrivit: aceasta nu este o problemă de statistică, ci de ciclul de viață al alertei. O alertă este o stare, nu un eveniment singular.
Episodul se aprinde. Card în Chat, sarcină în CRM, iar pentru cele critice și PagerDuty. Salvare în istoricul detecțiilor.
Severitatea devine limita inferioară. Un z-score otrăvit nu poate degrada alerta sau declanșa un duplicat. Liniște, cu excepția cazului în care incidentul escaladează real.
Episodul se stinge. După câteva zile fără o nouă alertă, dala dispare de pe dashboard. O nouă escaladare deschide un nou episod cu un cronometru resetat.
Nu orice anomalie este un atac
Să nu uităm însă că sistemul nu se hrănește doar cu incidente de securitate. Într-o zi, costul zilnic al unuia dintre conturile monitorizate de noi a crescut de 7,6 ori peste normă. Alerta a plecat, sarcina din CRM a ajuns la managerul de cont, iar acesta a confirmat cu clientul, în câteva zeci de minute, că este vorba de un antrenament de modele planificat pe Vertex AI. Episodul a fost pus pe silențios cu un singur clic, până la finalul zilei, cu escaladarea criticelor păstrată. Clientul a primit întrebarea „E al vostru?” la o oră după fapt, în locul unei surprize pe factura de peste o lună. Un sistem care nu știe să distingă rapid așteptatul de malițios îi învață pe oameni să ignore alertele, iar acesta e drumul direct spre o repetare a lunii mai.
Detalii care încep să doară abia în producție
Numerele fără context mint
Aceeași sumă într-un mediu reprezintă zgomot, în altul este incidentul lunii. Un prag comparat cu un număr brut înseamnă practic „1000 de orice”. De aceea, plasăm fiecare valoare în contextul unui cont specific, al amplorii și istoricului său, și le arătăm oamenilor sumele în formatul în care le cunosc de pe facturi.
Datele se strică în tăcere
Datele de facturare din diverse surse și perioade pot diferi ca structură și tipuri. Un cod care presupune că totul este la fel peste tot nu se va prăbuși cu vreo eroare, ci va schimba numerele în tăcere. Într-un sistem în care oamenii trebuie să aibă încredere, acesta este cel mai rău tip de eroare, așa că nicio presupunere despre date nu este considerată implicită la noi.
Oboseala cauzată de alerte este o datorie
Fiecare alertă inutilă scade încrederea în toate cele ulterioare. De aceea, sistemul are un întreg set de siguranțe împotriva spam-ului: deduplicare, cooldown-uri, silențiere și stingerea automată a episoadelor. Proiectăm pentru semnal, nu pentru volum.
Facturarea curge cu întârziere
Exportul poate „completa” ziua timp de mai multe ore. Cardul din iulie, de la ora 4:30, a arătat o sumă de câteva ori mai mică decât închiderea finală a zilei respective, iar contorul a crescut mult timp după blocarea traficului. Sistemul trebuie să știe acest lucru, altfel ar lua datele care ajung cu întârziere drept o escaladare și ar trezi oamenii fără motiv.
Un singur motor, două moduri de lucru
Aceeași arhitectură rulează astăzi în două moduri.
Primul este serviciul administrat. Acoperim mediul clientului cu monitorizarea noastră, alertele ajung în paralel la echipa noastră și la client, anomalia este clasificată și gestionată de un manager de cont concret, iar acolo unde ni s-au acordat permisiuni, reacționăm direct în loc să escaladăm doar. Povestea din iulie arată exact pe unde trece această graniță: fără permisiuni, până și cea mai bună detecție se termină cu un telefon către proprietarul mediului.
Al doilea mod decurge direct din construcție. De vreme ce motorul este fără stare și se bazează exclusiv pe exportul standard de facturare către BigQuery, poate fi instalat în orice mediu Google Cloud, inclusiv în unul pe care nu îl operăm zi de zi. Într-o astfel de implementare restrângem aria alertelor de la întregul cont de facturare la perspectiva proiectelor. Fiecare echipă vede anomaliile propriilor proiecte, cu praguri și canale de notificare proprii. Chat, e-mail sau webhook sunt, din perspectiva sistemului, adaptoare interschimbabile. Tot restul, de la ferestrele SQL la ciclul de viață al episodului, funcționează identic în ambele moduri.
Ce rezultă de aici pentru mediul tău
Indiferent dacă îți construiești singur așa ceva sau nu, câteva lucruri se transferă direct. Baseline-ul trebuie să fie comportamental și calculat per cont, pentru că un prag comun pentru toate mediile este o ficțiune. Alerta trebuie să aibă un ciclu de viață, pentru că fără hold, deduplicare și autoclose sistemul își devorează propria credibilitate în câteva săptămâni. Statistica doar detectează, decizia o ia contextul, adică maparea anomaliei pe client, responsabil și servicii concrete. Și cel mai simplu dintre adevărurile grele: costul este telemetrie de securitate. Finanțele se uită la el o dată pe lună, monitorizarea trebuie să ruleze non-stop.
Notă: sumele, momentele și desfășurarea ambelor incidente sunt reale și provin din rapoarte post-incident. Numele companiilor, detaliile de industrie și identificatorii conturilor au fost omise sau generalizate. Graficele sunt ilustrative: redau ordine de mărime reale, dar nu sunt capturi de ecran ale vreunei console reale. Articolul descrie sistemul în versiunea 4.x (2026).