Izgradnja računovodskega vmesnika API, ki prestane revizijo
Praktični vodnik o varnosti in revizijskih kontrolah, ki jih finančni vmesnik API potrebuje, preden mu nizozemska podjetja zaupajo svoje poslovne knjige.
Računovodski vmesnik API, ki ob zapisu plačila vrne kodo 200 OK, vam ni povedal skoraj ničesar. Ni potrdil, da je glavna knjiga zabeležila vknjižbo, da je imel izvajalec pooblastilo za to dejanje, da je znesek prestal preverjanje veljavnosti ali da je kdorkoli pristojen odobril transakcijo. Za podjetja na Nizozemskem, kjer davčni urad pričakuje, da so evidence sledljive in se hranijo sedem let, je ravno ta vrzel med „zahtevek je uspel“ in „poslovne knjige so pravilne“ prostor, kjer revizije spodletijo.
Pripravljenost na revizijo (audit-ready) je operativni načrtovalski cilj in ne certifikat. Pomeni, da vmesnik API ohranja celotno verigo: avtenticirani izvajalec do pooblaščenega dejanja do preverjene spremembe stanja do odobritve do rezultata v glavni knjigi do dokazov z vidnimi sledmi posegov. Vse v nadaljevanju govori o tem, kako to verigo zgraditi premišljeno, namesto da se zanašate na to, da bosta avtentikacija in protokol TLS poskrbela za vse.
Zakaj je računovodski vmesnik API „pripravljen na revizijo“
Revizor, ki rekonstruira transakcijo, mora odgovoriti na določeno zaporedje vprašanj. Kdo jo je sprožil? Ali je imel za to dovoljenje? Je sprememba prestala računovodsko preverjanje? Kdo jo je odobril? Kaj je zapisala glavna knjiga? Se ta zapis lahko spremeni za nazaj, ne da bi ostala sled?
Če vaš vmesnik API na podlagi lastnih dnevnikov in podatkovnega modela ne more odgovoriti na vseh šest vprašanj, ni pripravljen na revizijo, ne glede na to, kako čista je koda. Večina vmesnikov API dobro obravnava prvo vprašanje, preostala pa slabše.
Nadzorni elementi, ki zapolnjujejo to vrzel, spadajo v nekoliko skupin: eksplicitno računovodsko stanje, slojevita avtorizacija, omejena avtentikacija, idempotentni zapisi, strežniško preverjanje veljavnosti, ločitev dolžnosti in beleženje z vidnimi sledmi posegov. Med seboj se dopolnjujejo. Šibka avtorizacija spodkopava močan revizijski dnevnik, saj ne morete več zaupati, da je imel zabeleženi izvajalec sploh kakšen opravek z izvedbo tega dejanja.
Modeliranje računovodskih stanj pred modeliranjem končnih točk
Najpogostejša napaka pri načrtovanju je obravnava vsakega finančnega zapisa kot prosto urejanega predmeta z operacijami create, read, update, delete. Računovodstvo ne deluje tako in revizor bo takoj opazil, če je mogoče knjižbo v dnevniku tiho prepisati.
Vsak finančno pomemben vir potrebuje eksplicitni avtomat stanj (state machine). Zapis v dnevniku ali plačilo običajno preide skozi naslednje faze:
draft → submitted → approved → posted → settled
Popravki ne premikajo te poti nazaj. Napačna knjižba, ki je že bila knjižena, dobi povezano storno knjižbo ali izravnalni popravek. Izvirnik ostane nespremenjen.
Uporaben nabor pravil:
- Osnutke (drafts) lahko urejajo pooblaščeni uporabniki.
- Oddane zapise lahko urejajo samo vloge z ustreznimi dovoljenji ali pa se vrnejo v stanje osnutka.
- Odobreni zapisi zahtevajo nadzorovane popravke in novo odobritev.
- Knjiženih zapisov ni mogoče prepisati ali izbrisati, temveč jih je mogoče le stornirati ali popraviti.
- Spremembe v zaprtih obdobjih zahtevajo višjo raven avtorizacije, naveden razlog in revizijski dogodek.
Poskus nezakonitega prehodnega stanja, na primer urejanje knjiženega zapisa, mora vrniti stabilno napako in vseeno zapisati revizijski dogodek. Neuspešen poskus je namreč prav tako dokaz.
Tu pride do izraza nespremenljiva glavna knjiga z dvostavnim knjigovodstvom. Nordletova glavna knjiga je zasnovana tako, da se vsaka transakcija zabeleži kot uravnotežena, trajna vknjižba, pri čemer ravnovesje ob potrditvi uveljavlja podatkovni sprožilec, popravki pa se izvajajo prek storno knjižb namesto prepisovanj. Ta omejitev se med razvojem zdi stroga, med revizijo pa se spremeni v tisto, čemur vaš računovodja zaupa.
Avtorizirajte vsak zahtevek, ne samo z avtentikacijo
Avtentikacija dokazuje, kdo kliče. Ne pove pa ničesar o tem, ali sme ta klicatelj posegati v določen račun, dnevnik ali pravno osebo. Projekt za varnost vmesnikov API OWASP uvršča prekinjeno avtorizacijo na ravni predmetov (BOLA) na vrh seznama tveganj natanko zato, ker vmesniki API izpostavljajo identifikatorje predmetov, ki ob manjkajočih preverjanjih omogočajo enostaven dostop med najemniki (tenants).
Vsak zahtevek do finančnega vmesnika API je treba avtorizirati glede na kombinacijo dejavnikov in ne le na podlagi žetona:
- avtenticirani izvajalec
- odjemalska aplikacija ali servisni račun
- najemnik (tenant)
- pravna oseba
- ID vira
- zahtevana operacija
- trenutno stanje vira
- znesek ali prag transakcije
Dve praktični pravili sta pomembnejši od ostalih. Prvič, kontekst najemnika in uporabnika izpeljite iz avtenticirane identitete in zavrnite vsako trditev o najemniku ali vlogi, ki jo poda odjemalec in je v nasprotju s tem. Klicatelj ne sme nikoli imeti možnosti samovoljno določiti, za katero podjetje nastopa. Drugič, uporabite načelo privzete zavrnitve (deny-by-default). Če noben pravilnik izrecno ne odobri dejanja, to ni uspelo.
Preizkusite obe smeri. Vodoravni dostop, kjer en najemnik dostopa do podatkov drugega najemnika, in navpični dostop, kjer običajen uporabnik doseže funkcije odobritve, knjiženja ali izvoza. Obe vrsti sta pogosti, v računovodskih podatkih pa sta obe katastrofalni.
Nordletov model vlog z vlogami lastnika, skrbnika, računovodje, vodje, razvijalca in opazovalca v več podjetjih pod enim računom obstaja zato, da je ta ločitev uresničljiva in ne le želena. V vlogi razvijalca, ki lahko ustvarja osnutke računov, ne smete imeti možnosti sproščanja plačil.
Omejite žetone na poslovne zmožnosti, ne na glagole CRUD
Za delegiran dostop uporabite trenutna varnostna priporočila za OAuth 2.0 namesto ponovno uporabenih gesel ali obsežnih statičnih ključev API. RFC 9700 je trenutna najboljša praksa, ki postablja jasne zahteve za odjemalce in strežnike za avtorizacijo: preverjeni naslovi URL za preusmeritev, uporaba mehanizma PKCE, kjer je to ustrezno, preverjanje izdajatelja in občinstva, kratka življenjska doba žetonov za dostop ter rotacija žetonov za osveževanje s preklicem.
Odločitev o obsegu (scope) je točka, kjer se pokaže računovodsko specifično razmišljanje. Splošni obsegi, kot sta read in write, so za ločitev dolžnosti skoraj neuporabni. Obsegi se morajo ujemati z zmožnostmi:
journal:createinjournal:approvesta ločena obsega.- Ustvarjanje plačilnega navodila ne daje dovoljenja za njegovo sprostitev.
- Dovoljenje za izvoz se razlikuje od dovoljenja za branje, ker je množični izvoz pot za uhajanje podatkov.
Natančno opredelite, kje na tej lestvici stoji posamezen izdelek. Nordletovi ključi API vsebujejo obsege za posamezne module, kot sta sales:read in sales:write, ki se preverjajo ob vsakem dejanju. To ločuje module ter branje od pisanja, ne pa nujno ustvarjanja od odobritve; kjer danes potrebujete to natančnejšo delitev, jo uveljavite v lastni storitvi pred klicem.
Pri operacijah visoke vrednosti je vredno preveriti, ali je smiselna uporaba varnostnega profila FAPI 2.0. Zasnovan je za vmesnike API, ki varujejo občutljive finančne podatke, in ponuja močnejša zagotovila kot osnovni OAuth. Večina integracij za mala in srednja podjetja ne bo potrebovala celotnega profila, vendar so tokovi za sproščanje plačil in povezave z bankami tista mesta, kjer ga je vredno upoštevati.
Nordletova prijava brez gesla prek enkratnih povezav prek e-pošte odpravlja težavo s ponovno uporabnimi gesli za človeške uporabnike, kar pomeni eno poverilnico manj za rotacijo, puščanje ali lažno predstavljanje (phishing).
Zagotovite idempotentnost finančnih zapisov
Omrežja odpovedo sredi zahtevka. Odjemalec pošlje plačilni nalog, povezava pade, preden prispe odgovor, in odjemalec ponovi poizkus. Brez zaščite imate zdaj dve plačili.
Ključi idempotentnosti (idempotency keys) to rešujejo. Odjemalec z vsakim zapisom pošlje edinstven ključ; strežnik zabeleži ključ in njegov rezultat. Ponovni poskus z istim ključem vrne prvotni rezultat namesto ustvarjanja drugega vnosa. Nordlet sprejema glavo Idempotency-Key ob vsakem klicu, ki spreminja podatke, pri ponovnem poskusu z istim bremenom (payload) ponovno predvaja shranjeni odgovor in zavrne isti ključ s spremenjenim bremenom. Vsak računovodski vmesnik API, ki preskoči to funkcijo, bo sčasoma ustvaril podvojene vknjižbe v glavni knjigi, ki jih mora nekdo ročno razvozlavati.
To združite s strežniškim preverjanjem veljavnosti. Nikoli ne zaupajte odjemalcu, da bo preveril, ali bremena ustrezajo dobroimetjem, ali je stopnja DDV veljavna za državo in obdobje ter ali račun obstaja. Preverjanje se izvede na strežniku, pred prehodom stanja, zavrnjen zapis pa ustvari stabilno napako in revizijski zapis.
Dnevniki z vidnimi sledmi posegov in nizozemska hramba
Revizijski dnevnik je dokazna plast in ima drugačne zahteve kot običajni poslovni podatki. Zapisati mora odločitev o avtorizaciji, različico pravilnika, izvajalca, predmet, operacijo, prejšnje in novo stanje ter kodo razloga, nikoli pa ne sme beležiti skrivnosti ali popolnih poverilnic za plačilo.
Kritična lastnost so vidne sledi posegov (tamper-evidence). Če lahko skrbnik tiho ureja ali briše revizijske zapise, dnevnik ne dokazuje ničesar. Shramba z možnostjo samo dodajanja (append-only), kriptografsko veriženje ali hramba z možnostjo enkratnega zapisa (WORM) rešujejo ta problem. Poanta je v tem, da je treba vsako spremembo zaznati.
Hramba si zasluži lasten pravilnik, ločen od brisanja poslovnih zapisov. Na Nizozemskem je splošni rok hrambe za upravne evidence sedem let, za evidence v zvezi z nepremičninami pa deset let. Vaši običajni delovni postopki za branje podatkov in izbris po GDPR ne smejo uničiti zapisov ali revizijskih dokazov, ki jih še vedno pokriva pravilo zakonite hrambe. Neodvisno določite pravila zakonite hrambe (legal hold), arhiviranja in brisanj za revizijske dokaze ter jih preslikajte v jurisdikcije, v katerih delujete.
Zaklepanje obdobij to podpira na računovodski ravni. Ko je mesec zaključen, se vknjižbe v njem ne morejo več spremeniti brez povišane avtorizacije in zabeleženega razloga. Nordlet uveljavlja zaklepanje obdobij, tako da zaprti meseci ostanejo zaprti, kar pomeni, da zavrača vsako knjižbo z datumom znotraj zaklenjenega obdobja tudi prek vmesnika API, kar je ena prvih stvari, ki jih preveri nizozemski revizor.
Zavarujte robove: spletni kljuke, izvozi in integracije
Osrednji vmesnik API je običajno najbolje zavarovan del sistema. Robovi pa puščajo.
Spletne kljuke (webhooks) predstavljajo tveganje ponarejenih zahtevkov. Dogodek, kot je sale_invoice.paid, mora biti podpisan, da lahko prejemnik preveri, ali prihaja od vas, prejemniki pa morajo dostavo obravnavati kot vsaj-enkratno (at-least-once) in za preprečevanje podvajanja uporabiti ID dogodka. Nordlet podpiše vsako dostavo spletne kljuke s podpisom HMAC nad surovim telesom in ponovno poskuša neuspešne dostave z eksponentnim zaledenjenjem, zato mora prejemnik preveriti podpis in preprečiti podvajanje prek ID-ja dogodka, namesto da predvideva natanko-enkratno (exactly-once) dostavo.
Izvozi predstavljajo pot za množično uhajanje podatkov. Izvozi poročil v obliki XLSX, PDF ali JSON potegnejo velike količine finančnih podatkov v eni operaciji, zato potrebujejo lastno dovoljenje, omejitve pasovne širine in revizijsko beleženje. Integracije tretjih oseb, ki jih uporabljate, je treba obravnavati kot nepreverjen vnos in jih preveriti na enak način kot neposredne zahteve odjemalcev.
Kontrolni seznam pripravljenosti na revizijo za nizozemski računovodski vmesnik API
Uporabite ta seznam, preden trdite, da je integracija pripravljena na revizijo:
- Eksplicitni avtomat stanja za vsak finančni vir; knjiženih zapisov ni mogoče prepisati
- Avtorizacija na ravni predmetov in pravnih oseb za vsak zahtevek z načelom privzete zavrnitve
- Kontekst najemnika in vloge, izpeljan iz žetona, in ne iz trditev odjemalca
- OAuth 2.0 v skladu z RFC 9700; obsegi, ki temeljijo na zmožnostih; ločeno ustvarjanje in odobritev
- Ločitev dolžnosti, uveljavljena z vlogami, in ne samo z dokumentacijo
- Ključi idempotentnosti pri vseh finančnih zapisih
- Strežniško preverjanje računovodstva in DDV pred prehodi stanj
- Revizijski dnevnik z možnostjo samo dodajanja in vidnimi sledmi posegov s kodami razlogov
- Pravila hrambe in zakonite hrambe, preslikana v nizozemska obdobja (sedem let, deset za nepremičnine)
- Zaklepanje obdobij za zaključene mesece
- Podpisane spletne kljuke z odstranjevanjem podlage; omejeni izvozi z beleženjem in nadzorom hitrosti
Kaj bi zgradili najprej
Če bi jutri vgradili računovodstvo v nizozemsko platformo, bi začeli z modelom stanja in avtorizacijo na ravni predmetov, preden napišemo en sam poslovni končni del. Ti dve odločitvi omejujeta vse nadaljnje korake, naknadna vgradnja v sistem, ki je obravnaval vknjižbe v glavni knjigi kot urejane vrstice, pa je resnično boleča. Idempotentnost in revizijski dnevnik sta naslednja, ker ju je poceni dodati zgodaj in drago kasneje, ko podatki že tečejo.
Preostalo (omejeni žetoni, podpisane spletne kljuke, zaklepanje obdobij) sledi lažje, ko temelji stojijo. Vse to je mogoče preizkusiti v peskovniku podjetja, preden karkoli od tega pride v stik s produkcijskimi podatki.
FAQ
Ali vmesnik API, pripravljen na revizijo, pomeni, da je podjetje skladno s predpisi?
Ne, in o tem je vredno govoriti natančno. Pripravljenost na revizijo je načrtovalska lastnost sistema: glavna knjiga, kontrole in veriga dokazov so zgrajene tako, da je revizija lahko uspešna. Skladnost z določenim davčnim, računovodskim ali varnostnim okvirom je ločena ocena, ki te kontrole preslikava v določen standard. Dobro zgrajen vmesnik API olajšuje delo za doseganje skladnosti, vendar je ne nadomešča.
Kako dolgo je treba hraniti računovodske evidence na Nizozemskem?
Splošna obveznost je sedem let za upravne evidence, ki se podaljša na deset let za evidence, povezane z nepremičninami. Zgradite pravila hrambe in zakonite hrambe, ki jih vaši običajni delovni postopki brisanja ne morejo preglasiti.
Ali je statični ključ API dovolj za finančno integracijo?
Za avtomatizacijo med strežniki z ozkim obsegom delovanja lahko deluje, vendar je statične ključe, ki jih je mogoče ponovno uporabiti, težko rotirati in so nevarni, če puščajo. Za delegiran dostop in kakršen koli tok, namenjen človeškim uporabnikom, je OAuth 2.0 s kratkotrajnimi žetoni, omejenimi na zmožnosti, močnejša izbira.
Zakaj je idempotentnost tako pomembna prav za računovodstvo?
Ker je podvojen zapis v večini sistemov le nadloga, podvojen zapis v računovodstvu pa pomeni napačno številko v poslovnih knjigah, ki jo mora nekdo poiskati in stornirati. Ključi idempotentnosti naredijo ponovne poskuse varne namesto tvegane.
Nadaljnje branje
- Projekt za varnost vmesnikov API OWASP za trenutne kategorije tveganj vmesnikov API
- RFC 9700: Najboljša varnostna praksa za OAuth 2.0 za zahteve glede delegiranega dostopa
- Real-time EU VAT for developers in the Netherlands za vpogled v to, kako je davčna slika videti na Nizozemskem v praksi
- API conventions za obsege, idempotentnost, napake in podpisovanje spletnih kljuk