Kaip sukurti apskaitos API, kuris atlaikys auditą
Praktinis vadovas apie saugumo ir audito kontrolės priemones, kurių reikia finansiniam API, prieš Nyderlandų įmonėms patikint jam savo apskaitą.
Apskaitos API, kuris įrašius mokėjimą grąžina 200 OK, jums nepasako beveik nieko. Jis nepatvirtina, kad įrašas buvo užregistruotas didžiojoje knygoje, kad veiksmą atlikęs asmuo turėjo tam teisę, kad suma praėjo validaciją arba kad įgaliotas asmuo tai patvirtino. Nyderlandų įmonėms, iš kurių mokesčių administratorius tikisi, jog įrašai bus atkuriami ir saugomi septynerius metus, šis atotrūkis tarp „užklausa pavyko“ ir „apskaita teisinga“ yra būtent ta vieta, kur audito metu kyla problemų.
Pasirengimas auditui (angl. audit-ready) yra operacinis projektavimo tikslas, o ne sertifikatas. Tai reiškia, kad API išsaugo visą grandinę: nuo autentifikuoto subjekto, autorizuoto veiksmo, validuoto būsenos pakeitimo ir patvirtinimo iki rezultato didžiojoje knygoje bei nuo klastojimo apsaugoto (angl. tamper-evident) įrodymo. Viskas, kas aprašyta toliau, skirta sąmoningam šios grandinės kūrimui, užuot darius prielaidą, kad autentifikacija ir TLS viską išsprendžia savaime.
Kas paverčia apskaitos API „parengtu auditui“
Sandorį atkuriantis auditorius turi atsakyti į konkrečią klausimų seką. Kas jį inicijavo? Ar jie turėjo tam teisę? Ar pakeitimas praėjo apskaitos validaciją? Kas jį patvirtino? Kas buvo užregistruota didžiojoje knygoje? Ar šis įrašas gali būti pakeistas vėliau nepaliekant pėdsakų?
Jei jūsų API negali atsakyti į visus šešis klausimus remdamasis vien savo žurnalais (logs) ir duomenų modeliu, jis nėra parengtas auditui, kad ir koks tvarkingas būtų programinis kodas. Dauguma API puikiai susitvarko su pirmuoju klausimu, bet prastai su likusiais.
Kontrolės priemonės, panaikinančios šį atotrūkį, skirstomos į kelias grupes: aiški apskaitos būsena, sluoksniuota autorizacija (layered authorization), apribotos apimties autentifikacija (scoped authentication), idempotentiniai įrašymai, serverio pusės validacija, pareigų atskyrimas (segregation of duties) ir nuo klastojimo apsaugotas žurnalizavimas. Jos viena kitą sustiprina. Silpna autorizacija menkina stiprų audito žurnalą, nes nebegalite pasitikėti, kad žurnale užfiksuotas asmuo apskritai turėjo reikalų atlikti tą veiksmą.
Prieš projektuojant galinius taškus, sumodeliuokite apskaitos būsenas
Dažniausia projektavimo klaida – kiekvieno finansinio įrašo traktavimas kaip laisvai redaguojamo objekto naudojant create, read, update, delete operacijas. Apskaita taip neveikia, ir auditorius iškart pastebės, jei užregistruotas (posted) žurnalo įrašas gali būti tyliai perrašytas.
Kiekvienam finansine prasme reikšmingam ištekliui reikalingas aiškus būsenų automatas (state machine). Žurnalo įrašas arba mokėjimas paprastai pereina šiuos etapus:
draft → submitted → approved → posted → settled
Taisymai negrąžina šio kelio atgal. Klaidingam užregistruotam įrašui daromas susietas stornavimas (reversal) arba kompensuojamasis koregavimas (adjustment). Originalus įrašas lieka nepakeistas.
Veikiantis taisyklių rinkinys:
- Juodraščius (drafts) gali redaguoti autorizuoti vartotojai.
- Pateiktus (submitted) įrašus gali redaguoti tik tam teisę turinčios rolės arba jie gali būti grąžinti į juodraščio būseną.
- Patvirtintiems (approved) įrašams reikalingas kontroliuojamas pakeitimas ir naujas patvirtinimas.
- Užregistruoti (posted) įrašai negali būti perrašyti ar ištrinti, juos galima tik stornuoti arba koreguoti.
- Pakeitimams uždarytuose laikotarpiuose reikia aukštesnio lygio autorizacijos, nurodytos priežasties ir audito įvykio fiksavimo.
Bandymas atlikti neleistiną perėjimą, pavyzdžiui, redaguoti užregistruotą įrašą, turėtų grąžinti stabilią klaidą, bet vis tiek sukurti audito įrašą. Nepavykęs bandymas taip pat yra įrodymas.
Būtent čia savo vertę įrodo nekintama dvejybinio įrašo didžioji knyga. Nordlet didžioji knyga yra sukurta taip, kad kiekviena operacija būtų išsaugoma kaip subalansuotas, nuolatinis įrašas, kurio balansą tvirtinimo metu (commit time) užtikrina duomenų bazės trigeris, o taisymai atliekami stornuojant, o ne perrašant. Kuriant sistemą, šis apribojimas gali atrodyti varžantis, tačiau audito metu jis tampa tuo dalyku, kuriuo jūsų buhalteris pasitiki labiausiai.
Kiekvieną užklausą ne tik autentifikuokite, bet ir autorizuokite
Autentifikacija patvirtina, kas kreipiasi. Ji nieko nesako apie tai, ar besikreipiantysis turi teisę keisti konkrečią sąskaitą faktūrą, žurnalą ar juridinį asmenį. OWASP API Security Project pažeistą objekto lygio autorizaciją priskiria prie didžiausių rizikų būtent todėl, kad API atveria objektų identifikatorius, su kuriais, nesant tinkamų patikrų, lengva pasiekti kitų nuomininkų (cross-tenant) duomenis.
Kiekviena užklausa į finansinį API turėtų būti autorizuojama remiantis ne tik prieigos raktu (token), bet veiksnių deriniu:
- autentifikuotas subjektas
- kliento aplikacija arba paslaugos paskyra (service account)
- nuomininkas (tenant)
- juridinis asmuo
- ištekliaus ID
- prašoma atlikti operacija
- dabartinė ištekliaus būsena
- suma arba transakcijos limitas
Dvi praktinės taisyklės yra svarbesnės už kitas. Pirma, nuomininko ir vartotojo kontekstą išveskite iš autentifikuotos tapatybės ir atmeskite bet kokius kliento pateiktus nuomininko ar rolės reikalavimus (claims), kurie su tuo konfliktuoja. Besikreipiantysis niekada neturėtų galėti pats nurodyti, kurios įmonės vardu jis veikia. Antra, naudokite numatytąjį atmetimą (deny-by-default). Jei jokia politika aiškiai nesuteikia teisės veiksmui, jis turi būti atmestas.
Testuokite abi kryptis. Horizontalią prieigą, kai vienas nuomininkas pasiekia kito nuomininko duomenis, ir vertikalią prieigą, kai paprastas vartotojas pasiekia patvirtinimo, registravimo ar eksporto funkcijas. Abi situacijos yra dažnos ir abi yra katastrofiškos apskaitos duomenims.
Nordlet rolių modelis, apimantis savininko, administratoriaus, buhalterio, vadovo, programuotojo ir stebėtojo roles keliose įmonėse po viena paskyra, sukurtas tam, kad šis atskyrimas būtų realiai užtikrinamas, o ne tik siekiamybė. Programuotojo rolė, galinti kurti sąskaitų faktūrų juodraščius, neturėtų galėti vykdyti (release) mokėjimų.
Priskirkite prieigos raktų apimtis (scopes) verslo galimybėms, o ne CRUD veiksmažodžiams
Deleguotai prieigai naudokite naujausias OAuth 2.0 saugumo rekomendacijas, o ne daugkartinio naudojimo slaptažodžius ar plataus masto statinius API raktus. RFC 9700 yra dabartinė geriausia praktika, nustatanti aiškius reikalavimus klientams ir autorizacijos serveriams: validuotus peradresavimo URI, PKCE ten, kur taikoma, leidėjo (issuer) ir auditorijos patikras, trumpą prieigos raktų galiojimo laiką ir atnaujinimo raktų rotaciją su atšaukimu.
Būtent nustatant apimtis atsiskleidžia apskaitai specifiškas mąstymas. Bendrinės apimtys, tokios kaip read ir write, pareigų atskyrimui yra beveik bevertės. Apimtys turėtų būti susietos su konkrečiomis galimybėmis:
journal:createirjournal:approveyra atskiros apimtys.- Mokėjimo nurodymo sukūrimas nesuteikia teisės jo įvykdyti.
- Eksportavimo leidimas skiriasi nuo skaitymo leidimo, nes masinis eksportas yra duomenų nutekėjimo kelias.
Būkite tikslūs vertindami, kurioje šios skalės vietoje yra konkretus produktas. Nordlet API raktai turi modulių lygio apimtis, tokias kaip sales:read ir sales:write, kurios tikrinamos kiekvieno veiksmo metu, atskiriant modulius bei skaitymą nuo rašymo, bet ne sukūrimą nuo patvirtinimo; jei jums šiandien reikia dar smulkesnio padalijimo, užtikrinkite jį savo paslaugoje dar prieš atliekant API užklausą.
Didelės vertės operacijoms verta įvertinti, ar joms neturėtų būti taikomas FAPI 2.0 saugumo profilis. Jis sukurtas API, saugantiems jautrius finansinius duomenis, ir siūlo stipresnes garantijas nei bazinis OAuth. Daugumai smulkaus ir vidutinio verslo apskaitos integracijų neprireiks pilno profilio, tačiau mokėjimų vykdymo ir banko jungčių srautai yra tos vietos, kur verta apie jį pagalvoti.
Nordlet prisijungimas be slaptažodžio, naudojant vienkartines el. pašto nuorodas, pašalina daugkartinio naudojimo slaptažodžių problemą fiziniams vartotojams – tai vienu prisijungimo duomenų vienetu, kurį reikėtų rotuoti, kuris galėtų nutekėti ar būti išviliotas (phish), mažiau.
Padarykite finansinius įrašymus idempotentinius
Tinklai nutrūksta vidury užklausos. 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.
Idempotentiškumo raktai (idempotency keys) išsprendžia šią problemą. Klientas su kiekviena įrašymo užklausa siunčia unikalų raktą; serveris išsaugo raktą ir jo rezultatą. Pakartotinis bandymas su tuo pačiu raktu grąžina pradinį rezultatą, užuot sukūrus antrą įrašą. Nordlet priima Idempotency-Key antraštę kiekvienoje mutuojančioje užklausoje, atkartodama išsaugotą atsakymą pakartotinai bandant su tais pačiais duomenimis (payload) ir atmesdama tą patį raktą esant pakeistiems duomenims; bet koks apskaitos API, kuris praleidžia šią funkciją, ilgainiui sugeneruos besidubliuojančius didžiosios knygos įrašus, kuriuos kažkam teks aiškintis ir taisyti rankiniu būdu.
Suporuokite tai su serverio pusės validacija. Niekada nepasikliaukite klientu, kad jis patikrintų, ar debetas lygus kreditui, ar PVM tarifas yra galiojantis toje šalyje ir tuo laikotarpiu, arba ar sąskaita apskritai egzistuoja. Validacija vykdoma serveryje, prieš keičiant būseną, o atmestas įrašymas sugeneruoja stabilią klaidą ir audito įrašą.
Nuo klastojimo apsaugoti audito pėdsakai ir Nyderlandų duomenų saugojimo reikalavimai
Audito žurnalas yra įrodymų sluoksnis, ir jam taikomi kitokie reikalavimai nei įprastiems verslo duomenims. Jame turėtų būti fiksuojamas autorizacijos sprendimas, politikos versija, subjektas, objektas, operacija, ankstesnė ir nauja būsena bei priežasties kodas, jokiu būdu neįrašant paslapčių (secrets) ar pilnų mokėjimo duomenų.
Kritinė savybė yra apsauga nuo klastojimo. Jei administratorius gali tyliai redaguoti ar ištrinti audito įrašus, žurnalas nieko neįrodo. Tik papildoma (append-only) saugykla, kriptografinis susiejimas arba vienkartinio įrašymo saugojimas padeda tai išspręsti. Esmė ta, kad bet koks pakeitimas turi būti aptinkamas.
Duomenų saugojimas (retention) nusipelno atskiros politikos, nepriklausomos nuo verslo įrašų trynimo. Nyderlanduose bendrasis administracinių įrašų saugojimo terminas yra septyneri metai, o įrašams, susijusiems su nekilnojamuoju turtu, jis siekia dešimt metų. Jūsų įprasti duomenų trynimo ir BDAR ištrynimo darbo srautai neturi turėti galimybės sunaikinti įrašų ar audito įrodymų, kuriems vis dar taikoma teisinė saugojimo taisyklė. Apibrėžkite teisinio sulaikymo (legal hold), archyvavimo ir ištrynimo taisykles audito įrodymams atskirai ir susiekite jas su jurisdikcijomis, kuriose vykdote veiklą.
Laikotarpio uždarymas palaiko tai apskaitos lygmenyje. Uždarius mėnesį, jame esantys įrašai negali keistis be aukštesnio lygio autorizacijos ir žurnale užfiksuotos priežasties. Nordlet užtikrina laikotarpio uždarymą, todėl uždaryti mėnesiai lieka uždaryti, atmesdamas bet kokį registravimą, datuotą užrakinto laikotarpio ribose, net ir per API – tai vienas pirmųjų dalykų, kuriuos patikrina Nyderlandų auditorius.
Apsaugokite pakraščius: webhooks, eksportavimas ir integracijos
Pagrindinis API paprastai yra geriausiai apsaugota sistemos dalis. Pakraščiai „praleidžia“.
Webhooks kelia suklastotų užklausų riziką. Toks įvykis kaip sale_invoice.paid turėtų būti pasirašytas, kad gavėjas galėtų patvirtinti, jog jis atkeliavo iš jūsų, o gavėjai turėtų traktuoti pristatymą kaip „bent kartą“ (at-least-once) ir naudoti įvykio ID deduplikacijai. Nordlet pasirašo kiekvieną webhook pristatymą HMAC parašu, apimančiu neapdorotą (raw) užklausos kūną, ir pakartoja nepavykusius pristatymus su eksponentiniu atidėjimu (exponential backoff), todėl gavėjas privalo patikrinti parašą ir deduplikuoti pagal įvykio ID, užuot daręs prielaidą apie „tiksliai vieną kartą“ įvykstantį pristatymą.
Eksportavimas yra masinio duomenų nutekėjimo kelias. Ataskaitų eksportavimas XLSX, PDF ar JSON formatu vienos operacijos metu ištraukia didelius finansinių duomenų kiekius, todėl jiems reikalingi atskiri leidimai, užklausų srauto ribojimai (rate limits) ir audito žurnalizavimas. Trečiųjų šalių integracijos, kurias naudojate, turėtų būti traktuojamos kaip nepatikima įvestis ir validuojamos taip pat, kaip ir tiesioginės klientų užklausos.
Pasirengimo auditui kontrolinis sąrašas Nyderlandų apskaitos API
Pasinaudokite juo prieš tvirtindami, kad integracija yra parengta auditui:
- Aiški būsenų mašina (state machine) kiekvienam finansiniam ištekliui; užregistruoti įrašai negali būti perrašyti
- Objekto ir juridinio asmens lygio autorizacija kiekvienai užklausai, taikant numatytąjį atmetimą (deny-by-default)
- Nuomininko ir rolės kontekstas išvedamas iš prieigos rakto, o ne iš kliento pateiktų duomenų
- OAuth 2.0 pagal RFC 9700; galimybėmis grįstos apimtys; atskirtas kūrimas ir patvirtinimas
- Pareigų atskyrimas, faktiškai užtikrinamas per roles, o ne tik aprašytas dokumentacijoje
- Idempotentiškumo raktai visiems finansiniams įrašymams
- Serverio pusės apskaitos ir PVM validacija prieš būsenų perėjimus
- Tik papildomas, nuo klastojimo apsaugotas audito žurnalas su priežasčių kodais
- Duomenų saugojimo ir teisinio sulaikymo taisyklės, suderintos su Nyderlandų reikalaujamais laikotarpiais (septyneri metai, dešimt – nekilnojamajam turtui)
- Uždarytų mėnesių laikotarpio užrakinimas
- Pasirašyti webhooks su deduplikacija; apribotos apimties, limituojamo srauto, žurnalizuojamas eksportas
Ką mes kurtume pirmiausia
Jei rytoj integruotume apskaitą į Nyderlandų platformą, prieš rašydami bent vieną verslo logikos galinį tašką (endpoint), pradėtume nuo būsenų modelio ir objekto lygio autorizacijos. Šie du sprendimai apriboja viską, kas vyksta vėliau, ir pritaikyti juos retroaktyviai sistemai, kuri didžiosios knygos įrašus traktavo kaip redaguojamas eilutes, yra išties skausminga. Idempotentiškumas ir audito žurnalas eina po to, nes juos pigu pridėti anksti ir brangu įdiegti, kai duomenys jau pradeda plaukti.
Visi kiti dalykai – apribotos apimties raktų naudojimas, pasirašyti webhooks, laikotarpio uždarymas – įdiegiami kur kas lengviau, kai pamatas yra tvirtas. Visa tai galima išbandyti naudojant testavimo įmonę, dar prieš prisiliečiant prie gamybinių duomenų.
D.U.K.
Ar auditui parengtas API reiškia, kad verslas atitinka visus reikalavimus?
Ne, ir čia verta būti tiksliems. Pasirengimas auditui yra sistemos projektavimo savybė: didžioji knyga, kontrolės priemonės ir įrodymų grandinė yra sukurti taip, kad auditas galėtų būti sėkmingas. Atitiktis konkrečiam mokesčių, apskaitos ar saugumo pagrindui yra atskiras vertinimas, susiejantis šias kontrolės priemones su konkrečiu standartu. Gerai sukurtas API palengvina atitikties užtikrinimo procesą, bet jo nepakeičia.
Kiek laiko apskaitos įrašai turi būti saugomi Nyderlanduose?
Bendra prievolė yra septyneri metai administraciniams įrašams, o įrašams, susijusiems su nekilnojamuoju turtu, terminas pailgėja iki dešimties metų. Sukurkite duomenų saugojimo ir teisinio sulaikymo taisykles, kurių jūsų įprasti ištrynimo procesai negalėtų apeiti.
Ar statinio API rakto pakanka finansinei integracijai?
Griežtai apibrėžtos apimties serveris-serveris automatizacijai tai gali suveikti, tačiau daugkartinio naudojimo statinius raktus sunku rotuoti, o jiems nutekėjus kyla didelis pavojus. Deleguotai prieigai ir bet kokiam srautui, su kuriuo susiduria žmogus, stipresnis pasirinkimas yra OAuth 2.0 su trumpalaikiais, pagal galimybes apribotais (capability-scoped) prieigos raktais.
Kodėl idempotentiškumas toks svarbus būtent apskaitoje?
Todėl, kad besidubliuojantis įrašymas daugumoje sistemų tėra nepatogumas, o besidubliuojantis įrašymas apskaitoje reiškia neteisingus skaičius knygose, kuriuos kažkam teks surasti ir stornuoti. Idempotentiškumo raktai pakartotinius bandymus paverčia saugiais, o ne rizikingais.
Papildomai skaitykite
- OWASP API Security Project apie dabartines API rizikos kategorijas
- RFC 9700: OAuth 2.0 Security Best Current Practice apie deleguotosios prieigos reikalavimus
- ES PVM realiuoju laiku programuotojams Nyderlanduose apie tai, kaip Nyderlandų mokesčių sistema atrodo praktikoje
- API konvencijos apie apimtis, idempotentiškumą, klaidas ir webhook pasirašymą.