Kaip sukurti buhalterinę API, galinčią sėkmingai atlaikyti auditą
Praktinis vadovas apie saugumo ir audito valdiklius, kurių reikia finansinei API, kad Olandijos verslas patikėtų jai savo knygas.
Buhalterinė API, kuri grąžina 200 OK atsakymą į mokėjimo įrašymo užklausą, nepasako beveik nieko. Ji nepatvirtina, kad didžiojoje knygoje (ledger) buvo įregistruotas įrašas, kad vykdytojas turėjo teisę jį atlikti, kad suma praėjo patikrinimą arba kad kas nors, turintis įgaliojimus, ją patvirtino. Olandijos įmonėms, kuriose mokesčių inspekcija tikisi, kad apskaitos duomenys bus atkuriami ir saugomi septynerius metus, ši praraja tarp „užklausa pavyko“ ir „apskaita teisinga“ yra vieta, kur audito metu kyla problemų.
Paruoštumas auditui yra operacinio dizaino tikslas, o ne sertifikatas. Tai reiškia, kad API išlaiko pilną grandinę: autentiškas vykdytojas, įgaliotas veiksmas, patvirtintas būsenos pokytis, patvirtinimas, didžiosios knygos rezultatas ir klastojimui atsparūs įrodymai. Viskas, kas pateikiama toliau, yra apie sąmoningą šios grandinės kūrimą, o ne pasitikėjimą tuo, kad autentifikavimas ir TLS viską išspręs.
Dėl ko buhalterinė API tampa „paruošta auditui“
Auditorius, atkuriantis sandorį, turi atsakyti į tam tikrą klausimų seką. Kas jį inicijavo? Ar jiems tai buvo leista? Ar pokytis praėjo apskaitos patvirtinimą? Kas jį patvirtino? Ką įrašė didžioji knyga? Ar šis įrašas gali būti pakeistas po fakto nepaliekant jokių pėdsakų?
Jei jūsų API negali atsakyti į visus šešis klausimus iš savo žurnalų ir duomenų modelio, ji nėra paruošta auditui, nesvarbu, kaip švariai atrodo kodas. Dauguma API gerai tvarkosi su pirmuoju klausimu, o su likusiais – prastai.
Valdikliai, užpildantys šią spragą, skirstomi į kelias grupes: aiški apskaitos būsena, sluoksniuota autorizacija, apribotas autentifikavimas, operacijų dubliavimą išvengiantys įrašai (idempotent writes), serverio pusės patvirtinimai, pareigų atskyrimas ir klastojimui atsparus žurnalų rašymas. Jie vienas kitą papildo. Silpna autorizacija pakenkia stipriam audito žurnalui, nes nebegalite pasitikėti, kad žurnale užfiksuotas vykdytojas turėjo teisę atlikti šį veiksmą.
Apskaitos būsenų modeliavimas prieš galinių punktų (endpoints) modeliavimą
Dažniausia projektavimo klaida yra elgesys su kiekvienu finansiniu įrašu kaip su laisvai redaguojamu objektu, turinčiu create, read, update, delete funkcijas. Apskaita taip neveikia, ir auditorius iš karto pastebės, jei užregistruotas žurnalo įrašas gali būti tyliai perrašytas.
Kiekvienam finansinę reikšmę turinčiam ištekliui reikia aiškios būsenų mašinos. Žurnalo įrašas arba mokėjimas paprastai pereina šiuos etapus:
draft → submitted → approved → posted → settled
Korekcijos neatstato šio kelio atgal. Užregistruotas įrašas, kuriame yra klaida, gauna susietą storno įrašą (reversal) arba kompensacinį koregavimą. Originalas lieka nepaliestas.
Veikiančių taisyklių rinkinys:
- Juodraščius (draft) gali redaguoti įgalioti vartotojai.
- Pateiktus įrašus gali redaguoti tik tam tikrus vaidmenis turintys asmenys arba jie gali būti grąžinti į juodraščio būseną.
- Patvirtintiems įrašams reikalingas kontroliuojamas pakeitimas ir naujas patvirtinimas.
- Užregistruotų įrašų negalima perrašyti ar ištrinti, galima tik atšaukti arba koreguoti.
- Pakeitimams uždarytuose perioduose reikia aukštesnio lygio autorizacijos, nurodytos priežasties ir audito įvykio.
Mėginimas atlikti neteisėtiną perėjimą, pavyzdžiui, redaguoti užregistruotą įrašą, turi grąžinti stabilią klaidą ir vis tiek įrašyti audito įvykį. Nesėkmingas bandymas taip pat yra įrodymas.
Čia savo vertę įrodo nekintama dvejybinio įrašo didžioji knyga (immutable double-entry ledger). Nordlet didžioji knyga sukurta taip, kad kiekviena operacija nusileidžia kaip subalansuotas, nuolatinis įrašas, kurio balansą užcommitinimo metu užtikrina duomenų bazės trigeris, o korekcijos atliekamos per storno įrašus, o ne perrašinėjimą. Šis suvaržymas kūrimo metu atrodo ribojantis, tačiau audito metu tampa tuo, kuo jūsų buhalteris pasitiki.
Autorizuokite kiekvieną užklausą, o ne tik ją autentifikuokite
Autentifikavimas įrodo, kas skambina. Jis nieko nepasako apie tai, ar šis skambinusiojo subjektas gali liesti konkrečią sąskaitą faktūrą, žurnalą ar juridinį asmenį. OWASP API saugumo projektas sugadintą objektų lygio autorizaciją (broken object-level authorization) iškkelia į savo rizikos sąrašo viršų būtent todėl, kad API atskleidžia objektų identifikatorius, kurie nesant patikrinimų leidžia lengvai pasiekti kitų nuomininkų (tenants) duomenis.
Kiekviena užklausa į finansinę API turi būti autorizuojama pagal veiksnių derinį, o ne tik pagal žetoną:
- autentiškas vykdytojas;
- kliento programa arba paslaugos paskyra (service account);
- nuomininkas (tenant);
- juridinis asmuo;
- ištekliaus ID;
- pageidaujama operacija;
- esama ištekliaus būsena;
- suma arba operacijos slenkstis.
Dvi praktinės taisyklės yra svarbesnės už likusias. Pirma, nuomininko ir vartotojo kontekstą nustatykite iš autentiškos tapatybės ir atmeskite bet kokius kliento pateiktus nuomininko ar vaidmens teiginius (claims), kurie tam prieštarauja. Vartotojas niekada neturi galėti pats nurodyti, kuriai įmonei jis atstovauja. Antra, taikykite pagal nutylėjimą draudžiančią politiką (deny-by-default). Jei jokia taisyklė aiškiai nesuteikia leidimo veiksmui, jis nepavyksta.
Išbandykite abi puses. Horizontalioje prieigoje vienas nuomininkas pasiekia kito nuomininko duomenis, o vertikalioje prieigoje paprastas vartotojas pasiekia tvirtinimo, registravimo ar eksporto funkcijas. Abi jos yra dažnos, o buhalteriniuose duomenyse – katastrofiškos.
Nordlet vaidmenų modelis, apimantis savininko (owner), administratoriaus, buhalterio, vadovo (manager), programuotojo ir stebėtojo (viewer) vaidmenis keliose įmonėse po viena paskyra, sukurtas tam, kad šį atskyrimą būtų galima įgyvendinti praktiškai, o ne tik teoriškai. Programuotojo vaidmuo, galintis sukurti sąskaitų faktūrų juodraščius, neturėtų galėti išleisti mokėjimų.
Susiekite žetonus su verslo galimybėmis, o ne su CRUD veiksmais
Deleguotai prieigai naudokite dabartines OAuth 2.0 saugumo gaires, o ne daugkartinius slaptažodžius arba plataus masto statinius API raktus. RFC 9700 yra dabartinė geriausia praktika (Best Current Practice), nustatanti aiškius reikalavimus klientams ir autorizacijos serveriams: patvirtintus nukreipimo URL (redirect URIs), PKCE, kai taikoma, išdavėjo ir gavėjo patikrinimus, trumpą prieigos žetono galiojimo laiką ir atnaujinimo žetono rotaciją su atšaukimu.
Apsisprendimas dėl apimties (scoping) parodo apskaitos specifiką. Bendrinės apimtys, tokios kaip read ir write, pareigų atskyrimui yra beveik beverčiai. Apimtys turi atitikti konkrečias galimybes:
journal:createirjournal:approveyra atskiros apimtys.- Mokėjimo nurodymo sukūrimas nesuteikia leidimo jį įvykdyti.
- Eksporto leidimas skiriasi nuo skaitymo leidimo, nes masinis eksportas yra duomenų nutekėjimo kelias.
Būkite tikslūs dėl to, kur tam tikras produktas yra šioje skalėje. Nordlet API raktai turi moduliams specifines apimtis, tokias kaip sales:read ir sales:write, kurios tikrinamos kiekvieno veiksmo metu, atskiriančios modulius ir skaitymą nuo rašymo, bet ne sukūrimą nuo patvirtinimo; ten, kur šiandien reikia smulkesnio padalijimo, užtikrinkite tai savo paslaugoje prieš atliekant užklausą.
Operacijoms su didelėmis sumomis verta įvertinti, ar taikomas FAPI 2.0 saugumo profilis. Jis buvo sukurtas API, saugančioms jautrius finansinius duomenis, ir siūlo stipresnes garantijas nei bazinis OAuth. Daugumai smulkiojo ir vidutinio verslo apskaitos integracijų viso profilio nereikės, tačiau mokėjimų išleidimo ir banko ryšio srautai yra vietos, kur apie tai verta pagalvoti.
Nordlet slaptažodžių neturintis prisijungimas per vienkartines nuorodas el. paštu pašalina daugkartinio slaptažodžio problemą žmogiškiesiems vartotojams, todėl lieka vienu kredencialu mažiau, kurį reikėtų keisti, kuris galėtų nutekėti arba tapti sukčiavimo taikiniu.
Užtikrinkite finansinių įrašų operacijų dubliavimo prevenciją (idempotency)
Tinklai užklausos viduje kartais patiria trikčių. Klientas išsiunčia mokėjimo nurodymą, ryšys nutrūksta prieš gaunant atsakymą, ir klientas bando dar kartą. Be apsaugos priemonių dabar turėsite du mokėjimus.
Šią problemą išsprendžia operacijų dubliavimo prevencijos raktai (idempotency keys). Klientas su kiekvienu rašymo veiksmu siunčia unikalų raktą; serveris įrašo raktą ir jo rezultatą. Pakartotinis bandymas su tuo pačiu raktu grąžina originalų rezultatą, o ne sukuria antrą įrašą. Nordlet priima antraštę Idempotency-Key kiekvienam keičiančiam iškvietimui, pakartotinai atkuria išsaugotą atsakymą pakartotinio bandymo metu su tuo pačiu duomenų paketu (payload) ir atmeta tą patį raktą su pakeistu paketu, o bet kuri buhalterinė API, praleidžianti šią funkciją, galiausiai sugeneruos pasikartojančius didžiosios knygos įrašus, kuriuos kažkas turės išpainioti rankiniu būdu.
Sujunkite tai su serverio pusės patvirtinimu. Niekada nepasitikėkite klientu tikrinant, ar debetai lygus kreditams, ar PVM tarifas galioja šaliai ir periodui arba ar sąskaita egzistuoja. Patvirtinimas vykdomas serveryje, prieš būsenos pasikeitimą, o atmestas įrašymas sukuria stabilią klaidą ir audito įrašą.
Klastojimui atsparūs audito žurnalai ir Olandijos duomenų saugojimo taisyklės
Audito žurnalas yra įrodymų sluoksnis, kuriam taikomi kiti reikalavimai nei įprastiems verslo duomenims. Jis turėtų įrašyti autorizacijos sprendimą, politikos versiją, vykdytoją, objektą, operaciją, ankstesnę bei naują būseną ir priežasties kodą, niekada neįrašydamas paslapčių ar pilnų mokėjimo duomenų.
Kritinė savybė yra atsparumas klastojimui. Jei administratorius gali tyliai redaguoti arba ištrinti audito įrašus, žurnalas nieko neįrodo. Tai išsprendžia tik įrašymui skirtas saugykla (append-only storage), kriptografinis grandinių sudarymas arba rašymo vieną kartą ir saugojimo politika (write-once retention). Esmė ta, kad modifikacija turi būti aptinkama.
Duomenų saugojimas nusipelno atskiros politikos, atskirtos nuo verslo įrašų trynimo. Olandijoje bendras administracinių įrašų saugojimo laikotarpis yra septyneri metai, o įrašams, susijusiems su nekilnojamuoju turtu, jis siekia dešimt metų. Jūsų įprasti duomenų trynimo ir BDAR (GDPR) ištrynimo darbo srautai negali sunaikinti įrašų ar audito įrodymų, kuriems vis dar taikoma teisinė saugojimo taisyklė. Nustatykite teisinio sulaikymo (legal hold), archyvavimo ir trynimo taisykles audito įrodymams nepriklausomai ir pritaikykite jas jurisdikcijoms, kuriose veikiate.
Apskaitos lygmeniu tai palaiko periodų užrakinimas (period locking). Kai mėnuo uždaromas, jame esantys įrašai negali keistis be aukštesnio lygio autorizacijos ir užregistruotos priežasties. Nordlet taiko periodų užrakinimą, kad uždaryti mėnesiai liktų uždaryti, atmesdamas bet kokius įrašus su data užrakintame periode net ir per API, o tai yra vienas iš pirmųjų dalykų, kuriuos patikrina Olandijos auditorius.
Apsaugokite kraštus: žiniatinklio kabliukus (webhooks), eksportą ir integracijas
Pagrindinė API paprastai yra geriausiai apsaugota sistemos dalis. Kraštai praleidžia duomenis.
Žiniatinklio kabliukai kelia suklastotos užklausos riziką. Įvykis, pavyzdžiui, sale_invoice.paid, turi būti pasirašytas, kad gavėjas galėtų patvirtinti, jog jis atėjo iš jūsų, o gavėjai turėtų elgtis su pristatymu kaip su įvykstančiu bent kartą (at-least-once) ir naudoti įvykio ID dublikatų šalinimui. Nordlet pasirašo kiekvieną žiniatinklio kabliuko pristatymą HMAC parašu per neapdorotą turinį (raw body) ir pakartoja nepavykusius pristatymus su eksponentiniu delsa (exponential backoff), todėl gavėjas turi patvirtinti parašą ir pašalinti dublikatus pagal įvykio ID, o ne daryti prielaidą, kad pristatymas įvyks lygiai vieną kartą.
Eksportas yra masinio duomenų nutekėjimo kelias. Ataskaitų eksportas XLSX, PDF arba JSON formatais vienos operacijos metu ištraukia didelius finansinių duomenų kiekius, todėl jiems reikia atskiro leidimo, užklausų dažnio ribojimo (rate limits) ir audito žurnalų. Trečiųjų šalių integracijos, kurias vartojate, turi būti traktuojamos kaip nepatik A įvestis, tikrinamos taip pat, kaip tikrinate tiesiogines klientų užklausas.
Paruoštumo auditui kontrolinis sąrašas Olandijos buhalterinei API
Naudokite šį sąrašą prieš teigdami, kad integracija yra paruošta auditui:
- Aiški būsenų mašina kiekvienam finansiniam ištekliui; užregistruotų įrašų negalima perrašyti.
- Objekto ir juridinio asmens autorizacija kiekvienai užklausai, taikant pagal nutylėjimą draudžiančią politiką (deny-by-default).
- Nuomininko ir vaidmens kontekstas, gautas iš žetono, o ne iš kliento teiginių.
- OAuth 2.0 pagal RFC 9700; galimybėmis pagrįstos apimtys; atskiras sukūrimas ir patvirtinimas.
- Pareigų atskyrimas įgyvendintas per vaidmenis, o ne tik aprašytas dokumentacijoje.
- Operacijų dubliavimo prevencijos raktai (idempotency keys) visiems finansiniams įrašymams.
- Serverio pusės apskaitos ir PVM patvirtinimai prieš būsenos pasikeitimus.
- Tik įrašymui skirtas, klastojimui atsparus audito žurnalas su priežasties kodais.
- Duomenų saugojimo ir teisinio sulaikymo taisyklės, pritaikytos Olandijos periodams (septyneri metai, dešimt metų turtui).
- Periodų užrakinimas uždarytiems mėnesiams.
- Pasirašyti žiniatinklio kabliukai su dublikatų šalinimu; ribojamo dažnio, apribotų apimčių registruojami eksportai.
Ką pastatytume pirmiausia
Jei rytoj integruotume apskaitą į Olandijos platformą, pradėtume nuo būsenos modelio ir objektų lygio autorizacijos, neparašę nė vieno verslo galinio punkto. Šie du sprendimai apriboja viską, kas vyksta toliau, o jų diegimas atgaline data į sistemą, kurioje didžiosios knygos įrašai buvo traktuojami kaip redaguojamos eilutės, yra išties skausmingas. Idempotencija ir audito žurnalas atsiranda po to, nes juos pridėti ankstyvuoju etapas yra pigu, o vėliau, pradėjus plaukti duomenims – brangu.
Visa kita – apriboti žetonai, pasirašyti žiniatinklio kabliukai, periodų užrakinimas – seka lengviau, kai pamatas yra tvirtas. Visa tai gali būti išbandyta su smėlio dėžės įmone (sandbox company) prieš pradedant liesti gamybinius duomenis.
D.U.K.
Ar auditui paruošta API reiškia, kad verslas atitinka reikalavimus?
Ne, ir apie tai verta kalbėti tiksliai. Paruoštumas auditui yra sistemos dizaino savybė: didžioji knyga, valdikliai ir įrodymų grandinė yra sukurti taip, kad auditas galėtų pavykti. Atitiktis konkrečiam mokesčių, apskaitos ar saugumo kadrui yra atskiras vertinimas, kuris suderina šiuos valdiklius su tam tikru standartu. Gerai sukurta API palengvina atitikties užtikrinimo darbą, bet jos nepakeičia.
Kiek laiko Olandijoje reikia saugoti apskaitos įrašus?
Bendroji prievolė yra septyneri metai administraciniams įrašams, o įrašams, susijusiems su nekilnojamuoju turtu, ji pratęsiama iki dešimties metų. Sukurkite duomenų saugojimo ir teisinio sulaikymo taisykles, kurių jūsų įprasti trynimo darbo srautai negali ignoruoti.
Ar statinio API rakto pakanka finansinei integracijai?
Serverio ir serverio automatizavimui su siaura apimtimi tai gali veikti, tačiau daugkartinius statinius raktus sunku pakeisti, o jiems nutekėjus – pavojinga. Deleguotai prieigai ir bet kokiam su vartotojais sąveikaujančiam srautui OAuth 2.0 su trumpalaikiais, galimybėmis apribotais žetonais yra geresnis pasirinkimas.
Kodėl operacijų dubliavimo prevencija (idempotency) yra tokia svarbi būtent apskaitai?
Nes dubliuojantis įrašas daugelyje sistemų yra tik nepatogumas, o dubliuojantis įrašas apskaitoje yra neteisingas skaičius knygose, kurį kažkas turi rasti ir atšaukti. Dubliavimo prevencijos raktai pakartotinius bandymus padaro saugiais, o ne rizikingais.
Papildoma literatūra
- OWASP API saugumo projektas – dabartinės API rizikos kategorijos
- RFC 9700: OAuth 2.0 saugumo geriausia praktika – deleguotos prieigos reikalavimai
- Realaus laiko ES PVM kūrėjams Olandijoje – kaip Olandijos mokesčių situacija atrodo praktikoje
- API konvencijos – apimtys, idempotencija, klaidos ir žiniatinklio kabliukų pasirašymas