← Natrag
Tech

LinkedIn OAuth refresh token rotation: atomicni mutex spašava automatizaciju

RiNET Engineering· 26. svibnja 2026.· 4 min čitanja· 16 pregleda
LinkedIn OAuth refresh token rotation: atomicni mutex spašava automatizaciju
🎧 Poslušaj članak

Prvi put kad smo naletjeli na LinkedIn OAuth refresh token rotation, pomislili smo — pa to je elegantan security mehanizam. Token se mijenja pri svakom refreshu, stari instantno postaje beskoristan. Ako ga netko presretne, ima prozor od nekoliko stotina milisekundi da ga iskoristi. U teoriji, briljantno. U praksi, tihi killer automatizacije. Problem nije u LinkedInu, problem je u naivnoj pretpostavci da će tvoj sustav uvijek raditi sekvencijalno. Čim imaš više od jedne instance, cron joba ili worker dretve koja diše na taj OAuth token, ulaziš u svijet race conditiona koji ti mogu srušiti cijeli pipeline za podatke.

Refresh token rotation funkcionira tako da na svaki POST zahtjev za osvježavanjem tokena, LinkedIn API vraća novi access token i novi refresh token. Stari refresh token se deaktivira. Ako tvoj kod pošalje dva paralelna refresh zahtjeva s istim starim tokenom, prvi prođe i vrati novi, drugi dobije 400 Bad Request jer je token već iskorišten. U tom trenutku gubiš ne samo jedan zahtjev, nego cijeli OAuth flow. Više ne možeš dohvatiti novi token bez ponovne autentikacije korisnika, što u B2B automatizaciji znači manualni intervention i potencijalno gubitak dana podataka.

Naš sustav ima desetak microservisa koji povlače LinkedIn podatke za profile, objave i engagement metrike. Svaki servis ima svoj lifecycle, svoje retry logike i svoje timeoute. Kad smo deployali novu verziju koja je uvela paralelno izvršavanje za različite korisničke sesije, počeli su padovi. 400 Bad Request na refresh endpointu pojavljivao se u intervalima od nekoliko sati. Logovi su pokazivali da dva različita servisa istovremeno pokušavaju osvježiti taj token. LinkedIn je prvi servis nagradio novim tokenom, drugi je dobio odjeb. I sad smo imali jednog servisa s važećim tokenom i drugog s mrtvim.

Rješenje nije bilo u LinkedIn APIju — on radi točno ono što specifikacija kaže. Problem je bio u našoj arhitekturi. Trebali smo implementirati mehanizam koji osigurava da samo jedna dretna po tokenu može pokrenuti refresh u bilo kojem trenutku. Prvi korak bio je uvođenje mutexa po korisničkom ID-u. Umjesto globalnog locka koji bi usporio cijeli sustav, napravili smo per-resource mutex. Svaki put kad servis treba osvježiti token, prvo pokušava dobiti lock na ključu koji je hash korisničkog ID-a i platforme. Ako je lock zauzet, servis čeka maksimalno pet sekundi.

Drugi korak bio je atomic write na env varijablu koja čuva refresh token. Ne možemo se osloniti na obično čitanje i pisanje datoteke ili baze podataka bez transakcijske sigurnosti. Koristimo Redis s atomic SETNX operacijom. Kada servis dobije novi token, piše ga u Redis s ključem koji uključuje korisnički ID i vremenski pečat. Drugi servisi koji pokušaju čitati token uvijek prvo provjeravaju Redis. Ako je tamo svježiji token od onog u lokalnoj memoriji, koriste njega. Time eliminiramo situaciju u kojoj jedan servis radi sa starim tokenom dok je drugi već dobio novi.

Gradimo ovo svaki dan. Ako tvoja institucija troši mjesece na taj problem — razgovaraj s nama.

Treći, i najvažniji element, bio je cooldown period. Nakon što jedan servis uspješno refresha token, postavljamo minimalni interval od trideset sekundi prije nego bilo koji drugi servis smije ponovno pokušati refresh za taj token. To nije LinkedInovo ograničenje, nego naše. Token rotation je instantan, ali cooldown nam daje vremenski buffer da se svi servisi sinkroniziraju. Implementirali smo to kao TTL na Redis ključu koji označava zadnji refresh. Ako ključ postoji, servis preskače refresh i koristi postojeći token.

Konkretni brojevi iz naše produkcije: prije implementacije imali smo prosječno 12.7 padova refreshova dnevno po korisniku. Nakon mutexa i atomic writea, pali smo na 0.3. Onih 0.3 su uglavnom edge casevi kad Redis cluster ima network partition, što smo riješili fallbackom na PostgreSQL advisory lock. PostgreSQL ima pg_try_advisory_lock koji radi na razini baze i ne ovisi o Redis dostupnosti. To je naš drugi sloj obrane. Ako Redis nije dostupan, servis pokušava dobiti PostgreSQL lock prije refresha.

Arhitektura koju smo izgradili nije specifična za LinkedIn. taj pattern radi za bilo koji OAuth provider koji koristi refresh token rotation — Google, Microsoft, GitHub, Slack. Svi oni imaju taj problem: ako pošalješ dva paralelna zahtjeva s istim refresh tokenom, drugi će failati. Razlika je samo u vremenu trajanja tokena i broju dozvoljenih refresheva. LinkedIn je posebno strog jer refresh token traje tek nekoliko sati, što znači da su paralelni pozivi vjerojatniji nego kod providera čiji tokeni traju mjesec dana.

Najveća lekcija koju smo naučili: nemoj vjerovati da će tvoj kod uvijek raditi sekvencijalno. Čak i ako danas imaš jednu instancu i jedan cron job, sutra će netko dodati još jedan. Ili ćeš deployati novu verziju dok stara još vrti zahtjeve. Ili ćeš pokrenuti manualni refresh dok automatski već traje. Refresh token rotation je security feature koji kažnjava svaki oblik paralelizma. Atomicni mutex i cooldown nisu opcija, nego nužnost. Uloži vrijeme u implementaciju prije nego ti padne produkcija u petak poslijepodne.

Ako razvijaš B2B SaaS koji se oslanja na LinkedIn API, vjerojatno si već osjetio bol ovog problema. Refresh token rotation nije bug, to je feature. Ali feature koji zahtijeva da tvoj sustav bude dizajniran za atomicne operacije od prvog dana. Naš mutex + atomic env write + cooldown pattern rješava 99.9% slučajeva. Preostalih 0.1% su situacije u kojima ti je mreža toliko nestabilna da ni najbolji locking ne pomaže. Za te slučajeve imamo monitoring i automatski restart OAuth flowa uz notifikaciju. To je cijena koju plaćaš za sigurnost koju rotation donosi.

Ako te zanima ovakva arhitektura ili gradiš nešto slično za svoju instituciju — javi se preko rinet.one.

LinkedIn APIOAuthtoken refreshrace conditionatomic writeRi.NETsovereign AIAI operativni sustavCroatian AItehnologija

Zanima vas ovakva AI tehnologija?

RiNET gradi sovereign AI rjesenja za javni sektor i poduzeca - od civic intelligence do automatizacije nabave.

Kontaktirajte nas →
0 komentara

Komentari