Tvorba účtovného API, ktoré prežije audit
Praktický sprievodca bezpečnostnými kontrolami a kontrolami pre audit, ktoré finančné API potrebuje predtým, než mu holandské firmy zveria svoje účtovníctvo.
Účtovné API, ktoré pri zápise platby vráti odpoveď 200 OK, vám neprezradilo takmer nič. Nepotvrdilo, že hlavná kniha (ledger) záznam zaevidovala, že aktér mal na to oprávnenie, prešlo overením sumy, ani to, že akákoľvek oprávnená osoba operáciu schválila. Pre firmy v Holandsku, kde daňový úrad vyžaduje, aby boli záznamy rekonštruovateľné a uchovávané sedem rokov, predstavuje práve táto priepasť medzi „požiadavka bola úspešná“ a „účtovníctvo je správne“ miesto, kde audity zlyhávajú.
Pripravenosť na audit (audit-ready) je cieľom operačného dizajnu, nie certifikátom. Znamená to, že API zachováva kompletný reťazec: autentifikovaný aktér - autorizovaná akcia - overená zmena stavu - schválenie - výsledok v hlavnej knihe (ledger) - dôkaz odolný voči neoprávnenej manipulácii. Všetko, čo je uvedené nižšie, sa týka zámerného budovania tohto reťazca namiesto spoliehania sa na to, že autentifikácia a TLS všetko vyriešia.
Čo robí účtovné API „pripraveným na audit“
Audítor, ktorý rekonštruuje transakciu, potrebuje poznať konkrétnu postupnosť odpovedí na otázky. Kto ju inicioval? Mal na to povolenie? Prešla zmena účtovným overením? Kto ju schválil? Čo zaznamenala hlavná kniha (ledger)? Dá sa tento záznam dodatočne upraviť bez toho, aby to zanechalo stopu?
Ak vaše API nedokáže odpovedať na všetkých šesť otázok pomocou vlastných logov a dátového modelu, nie je pripravené na audit bez ohľadu na to, aký čistý sa zdá byť jeho kód. Väčšina API si dobre poradí s prvou otázkou, ale so zvyšnými zle.
Kontroly, ktoré túto priepasť zacelia, spadajú do niekoľkých skupín: explicitný účtovný stav, vrstvená autorizácia, obmedzená autentifikácia, idempotentné zápisy, validácia na strane servera, oddelenie povinností (segregation of duties) a logovanie odolné voči neoprávnenej manipulácii. Tieto prvky sa navzájom dopĺňajú. Slabá autorizácia podkopáva silný auditný log, pretože už nemôžete dôverovať, že prihlásený aktér mal vôbec právo túto akciu vykonať.
Modelujte stavy účtovníctva skôr, než začnete modelovať koncové body (endpoints)
Najbežnejšou chybou pri navrhovaní je prístup, kedy sa s každým finančným záznamom zaobchádza ako s voľne upraviteľným objektom s operáciami create, read, update, delete. Účtovníctvo takto nefunguje a audítor si okamžite všimne, ak sa zaúčtovaný zápis v denníku dá ticho prepísať.
Každý finančne významný zdroj vyžaduje explicitný stavový automat (state machine). Záznam v denníku alebo platba zvyčajne prechádzajú týmito fázami:
draft → submitted → approved → posted → settled
Opravy túto cestu nevracajú späť. Nesprávny zaúčtovaný záznam získa prepojenú korekciu alebo vyrovnávaciu položku. Pôvodný záznam zostáva nedotknutý.
Použiteľný súbor pravidiel:
- Koncepty (drafts) môžu upravovať oprávnení používatelia.
- Predložené záznamy môžu upravovať iba oprávnené role, prípadne ich možno vrátiť do stavu konceptu.
- Schválené záznamy vyžadujú kontrolovanú úpravu a nové schválenie.
- Zaúčtované záznamy nemožno prepísať ani vymazať, dajú sa iba opraviť alebo korigovať.
- Zmeny v uzatvorenom období vyžadujú vyššie oprávnenie, uvedenie dôvodu a vytvorenie auditnej udalosti.
Pokus o neoprávnený prechod, napríklad úpravu zaúčtovaného záznamu, by mal vrátiť stabilnú chybovú hmlásenie a zároveň zapísať záznam do auditu. Neúspešný pokus je totiž tiež dôkazom.
Tu prichádza k slovu imutabilná podvojná hlavná kniha (double-entry ledger). Hlavná kniha produktu Nordlet je navrhnutá tak, že každá transakcia sa zapíše ako vyrovnaný, trvalý záznam, pričom rovnováha sa vynucuje databázovým triggrom v čase potvrdenia (commit) a opravy sa realizujú prostredníctvom korekcií namiesto prepisovania. Toto obmedzenie sa počas vývoja zdá byť prísne, no počas auditu sa mení na presne to, čomu váš účtovník dôveruje.
Autorizujte každú požiadavku, nielen ju autentifikujte
Autentifikácia dokazuje, kto volá rozhranie. Hovorí nič o tom, či tento volajúci môže manipulovať s konkrétnou faktúrou, denníkom alebo právnickou osobou. Projekt OWASP API Security umiestňuje narušenú autorizáciu na úrovni objektov (broken object-level authorization) na vrch svojho zoznamu rizík práve preto, že API sprístupňujú identifikátory objektov, ktoré v prípade absencie kontrol uľahčujú prístup naprieč rôznymi nájomníkmi (tenants).
Každá požiadavka na finančné API by mala byť autorizovaná na základe kombinácie viacerých faktorov, nielen tokenu:
- autentifikovaný aktér
- klientska aplikácia alebo servisný účet
- nájomník (tenant)
- právnická osoba
- ID zdroja
- požadovaná operácia
- aktuálny stav zdroja
- suma alebo transakčný limit
Dve praktické pravidlá sú dôležitejšie ako ostatné. Po prvé, kontext nájomníka a používateľa odvoďte z autentifikovanej identity a odmietnite akýkoľvek nájomnícky alebo rolou podmienený nárok (claim) dodaný klientom, ktorý je s ňou v rozpore. Volajúci by nikdy nemal mať možnosť tvrdiť, v mene ktorej spoločnosti koná. Po druhé, používajte prístup odmietnutia predvolene (deny-by-default). Ak žiadna politika výslovne nepovoľuje danú akciu, táto zlyhá.
Testujte oba smery. Horizontálny prístup, kde jeden nájomník pristupuje k údajom iného nájomníka, a vertikálny prístup, kde bežný používateľ pristupuje k funkciám schvaľovania, účtovania alebo exportu. Obidva sú bežné a v účtovných dátach katastrofálne.
Rola v systéme Nordlet s oprávneniami vlastníka (owner), administrátora (admin), účtovníka (accountant), manažéra (manager), vývojára (developer) a pozorovateľa (viewer) naprieč viacerými spoločnosťami pod jedným účtom existuje preto, aby bolo toto oddelenie vynútiteľné, a nie len teoretické. Rola vývojára, ktorá môže vytvárať koncepty faktúr, by nemala byť schopná uvoľňovať platby.
Obmedzte tokeny na podnikové schopnosti (capabilities), nie na CRUD slovesá
V prípade delegovaného prístupu používajte súčasné bezpečnostné odporúčania pre OAuth 2.0 namiesto opakovane použiteľných hesiel alebo širokých statických kľúčov API. RFC 9700 predstavuje aktuálny štandard najlepšej praxe (Best Current Practice) a stanovuje jasné požiadavky na klientov a autorizačné servery: overené presmerovacie URI, PKCE tam, kde je to možné, kontroly vydavateľa a cieľovej audience, krátku životnosť prístupových tokenov a rotáciu obnovovacích tokenov (refresh-token) spolu s ich revokáciou.
Rozhodovanie o rozsahu oprávnení (scoping) je miestom, kde sa prejavuje uvažovanie špecifické pre účtovníctvo. Všeobecné rozsahy ako read a write sú na oddelenie povinností takmer nepoužiteľné. Rozsahy by mali zodpovedať konkrétnym schopnostiam:
journal:createajournal:approvesú samostatné rozsahy.- Vytvorenie platobného príkazu neudeluje oprávnenie na jeho uvoľnenie.
- Oprávnenie na export sa líši od oprávnenia na čítanie, pretože hromadný export predstavuje cestu úniku údajov.
Buďte presní v tom, kde sa daný produkt na tejto škále nachádza. API kľúče v systéme Nordlet obsahujú rozsahy pre jednotlivé moduly, ako napríklad sales:read a sales:write, ktoré sa kontrolujú pri každej akcii. To oddeľuje moduly a čítanie od zápisu, nie však vytvorenie od schválenia – ak dnes potrebujete toto jemnejšie rozdelenie, vynúťte ho vo svojej vlastnej službe pred uskutočnením volania.
Pri operáciách s vysokou hodnotou stojí za zváženie, či sa na ne vzťahuje bezpečnostný profil FAPI 2.0 (FAPI 2.0 Security Profile). Bol navrhnutý pre API chrániace citlivé finančné údaje a ponúka silnejšie záruky ako základné OAuth. Väčšina integrácií pre malé a stredné podniky (SMB) plný profil nebude potrebovať, ale toky uvoľňovania platieb a bankových pripojení sú miestom, kde ho treba zvážiť.
Bezheslové prihlásenie v systéme Nordlet prostredníctvom jednorazových e-mailových odkazov odstraňuje problém opakovane použiteľných hesiel pre ľudských používateľov, čo znamená o jedno poverenie menej, ktoré by bolo nutné rotovať, ktoré by mohlo uniknúť alebo sa stať terčom phishingových útokov.
Zabezpečte, aby finančné zápisy boli idempotentné
Sieťové pripojenia uprostred požiadavky zlyhávajú. Klient odošle platobný príkaz, spojenie sa preruší skôr, ako dorazí odpoveď, a klient požiadavku zopakuje. Bez ochrany máte zrazu dve platby.
Tento problém riešia identifikačné kľúče pre idempotenciu (idempotency keys). Klient odošle s každým zápisom jedinečný kľúč; server zaznamená kľúč a jeho výsledok. Opakovaný pokus s rovnakým kľúčom vráti pôvodný výsledok namiesto vytvorenia druhého záznamu. Nordlet akceptuje hlavičku Idempotency-Key pri každom mutujúcom volaní, pričom pri opakovanom pokuse s rovnakým obsahom (payload) prehraje uloženú odpoveď a rovnaký kľúč s pozmeneným obsahom odmietne. Každé účtovné API, ktoré tento prvok vynechá, nakoniec vyprodukuje duplicitné položky v hlavnej knihe, ktoré potom niekto musí manuálne rozpletať.
Spojte to s validáciou na strane servera. Nikdy nevěřte klientovi, že skontroloval, či sa strany má dať rovnať, či je sadzba DPH platná pre danú krajinu a obdobie, alebo či účet existuje. Overenie prebieha na serveri, pred prechodom stavu, pričom zamietnutý zápis vytvorí stabilnú chybu a auditný záznam.
Auditné záznamy odolné voči manipulácii a holandské uchovávanie údajov
Auditný log je dôkazová vrstva a má iné požiadavky ako bežné obchodné údaje. Mal by zaznamenávať rozhodnutie o autorizácii, verziu politiky, aktéra, objekt, operáciu, predchádzajúci a nový stav, ako aj kód dôvodu, pričom nikdy nesmie zaznamenávať tajné údaje ani úplné platobné údaje.
Kritickou vlastnosťou je odolnosť voči neoprávnenej manipulácii (tamper-evidence). Ak administrátor môže potichu upravovať alebo vymazávať auditné záznamy, log nič nedokazuje. Úložisko typu append-only (iba na pridávanie), kryptografické reťazenie alebo uchovávanie typu write-once (zápis raz) toto všetko riešia. Ide o to, aby bola akákoľvek úprava zistiteľná.
Uchovávanie údajov (retention) si zaslúži vlastnú politiku, oddelenú od mazania bežných obchodných záznamov. V Holandsku je všeobecná lehota na uchovávanie administratívnych záznamov sedem rokov a v prípade záznamov týkajúcich sa nehnuteľného majetku až desať rokov. Vaše bežné procesy vymazávania údajov a dodržiavania GDPR nesmú mať možnosť zničiť záznamy alebo dôkazy z auditu, na ktoré sa stále vzťahuje zákonná povinnosť uchovávania. Definujte pravidlá pre právnu blokáciu (legal hold), archiváciu a mazanie auditných dôkazov nezávisle a priraďte ich k jurisdikciám, v ktorých pôsobíte.
Uzamykanie období (period locking) toto podporuje na účtovnej vrstve. Akonáhle je mesiac uzavretý, záznamy v ňom nemožno zmeniť bez vyššieho oprávnenia a zaznamenaného dôvodu. Nordlet vynucuje uzamykanie období tak, aby uzavreté mesiace zostali uzavreté, pričom odmieta akékoľvek zaúčtovanie s dátumom spadajúcim do uzatvoreného obdobia, a to aj prostredníctvom API, čo je jedna z prvých vecí, ktoré holandský audítor kontroluje.
Zabezpečte okraje: webhooks, exporty a integrácie
Základné API býva zvyčajne najlepšie zabezpečenou časťou systému. Okraje systému však prepúšťajú dáta.
Webhooky predstavujú riziko sfalšovaných požiadaviek. Udalosť typu sale_invoice.paid by mala byť podpísaná, aby prijímateľ mohol overiť, že prišla od vás, pričom prijímatelia by mali doručenie chápať v režime aspoň raz (at-least-once) a na deduplikáciu používať ID udalosti. Nordlet podpisuje každé doručenie webhooku pomocou HMAC podpisu surového tela (raw body) a neúspešné doručenia opakuje s exponenciálnym rastom oneskorenia (exponential backoff). Prijímateľ tak musí overiť podpis a vykonať deduplikáciu podľa ID udalosti namiesto toho, aby predpokladal doručenie presne raz (exactly-once).
Exporty predstavujú cestu hromadného úniku údajov. Exporty zostávok vo formátoch XLSX, PDF alebo JSON sťahujú veľké objemy finančných údajov v rámci jednej operácie, preto vyžadujú vlastné oprávnenie, obmedzenia frekvencie (rate limits) a auditné logovanie. S integráciami tretích strán, ktoré využívate, by sa malo zaobchádzať ako s nedôveryhodným vstupom a overovať ich rovnako, ako overujete priame požiadavky klientov.
Kontrolný zoznam pripravenosti na audit pre holandské účtovné API
Použite tento zoznam predtým, ako vyhlásite, že integrácia je pripravená na audit:
- Explicitný stavový automat (state machine) pre každý finančný zdroj; zaúčtované položky nemožno prepísať
- Autorizácia na úrovni objektov a právnických osôb pri každej požiadavke, s predvoleným odmietnutím (deny-by-default)
- Kontext nájomníka a role odvodený z tokenu, nie z klientskych nárokov (claims)
- OAuth 2.0 podľa RFC 9700; rozsahy založené na schopnostiach (capabilities); oddelenie vytvorenia a schválenia
- Oddelenie povinností vynútené v rolách, nielen zdokumentované
- Identifikačné kľúče pre idempotenciu (idempotency keys) pri všetkých finančných zápisoch
- Účtovná validácia a validácia DPH na strane servera pred prechodom stavu
- Auditný log typu append-only, odolný voči neoprávnenej manipulácii, s kódmi dôvodov
- Pravidlá uchovávania a právnej blokácie prispôsobené holandským obdobiam (sedem rokov, desať pre nehnuteľnosti)
- Uzamykanie období (period locking) pre uzatvorené mesiace
- Podpísané webhooky s deduplikáciou; exporty s obmedzeným rozsahom a frekvenciou, ktoré sa logujú
Čo by sme vybudovali ako prvé
Ak by sme mali zajtra integrovať účtovníctvo do holandskej platformy, začali by sme modelom stavov a autorizáciou na úrovni objektov, a to ešte pred napísaním jediného podnikového koncového bodu. Tieto dve rozhodnutia ovplyvňujú všetko ostatné a ich spätné implementovanie do systému, ktorý zaobchádzal so záznamami v hlavnej knihe ako s upraviteľnými riadkami, je úprimne bolestivé. Idempotencia a auditný log prichádzajú na rad hneď potom, pretože ich skoré pridanie je lacné, kým pridanie po začatí toku údajov je drahé.
Zvyšok – tokeny s obmedzeným rozsahom, podpísané webhooky, uzamykanie období – nasleduje oveľa jednoduchšie, keď základ pevne stojí. Všetko z toho je možné vyskúšať v sandboxovej spoločnosti predtým, než sa čokoľvek dotkne produkčných dát.
FAQ
Znamená API pripravené na audit, že firma je v súlade s predpismi (compliant)?
Nie, a v tomto bode je dôležité byť presný. Pripravenosť na audit je vlastnosť dizajnu systému: hlavná kniha, kontroly a dôkazový reťazec sú postavené tak, aby audit mohol prebehnúť úspešne. Súlad s konkrétnym daňovým, účtovným alebo bezpečnostným rámcom predstavuje samostatné posúdenie, ktoré priraďuje tieto kontroly k menovitému štandardu. Dobre navrhnuté API uľahčuje prácu so súladom, ale nenahrádza ho.
Ako dlho sa musia účtovné záznamy v Holandsku uchovávať?
Všeobecná povinnosť je sedem rokov pre administratívne záznamy, pričom sa predlžuje na desať rokov pre záznamy spojené s nehnuteľným majetkom. Vytvorte pravidlá uchovávania a právnej blokácie, ktoré vaše bežné procesy mazania nedokážu obísť.
Stačí pre finančnú integráciu statický API kľúč?
Pre automatizáciu typu server-server s úzkym rozsahom to fungovať môže, ale opakovane použiteľné statické kľúče sa ťažko rotujú a v prípade úniku sú nebezpečné. Pre delegovaný prístup a akýkoľvek tok určený pre ľudí je lepšou voľbou OAuth 2.0 s krátkodobými tokenmi obmedzenými na konkrétne schopnosti.
Prečo je idempotencia pre účtovníctvo taká dôležitá?
Pretože duplicitný zápis vo väčšine systémov predstavuje len nepríjemnosť, zatiaľ čo duplicitný zápis v účtovníctve znamená nesprávne číslo v knihách, ktoré musí niekto nájsť a opraviť. Identifikačné kľúče robia opakovane vykonané požiadavky bezpečnými namiesto rizikových.
Ďalšie čítanie
- OWASP API Security Project pre aktuálne kategórie rizík API
- RFC 9700: OAuth 2.0 Security Best Current Practice pre požiadavky na delegovaný prístup
- Real-time EU VAT for developers in the Netherlands o tom, ako vyzerá holandská daňová realita v praxi
- API conventions pre rozsahy, idempotenciu, chyby a podpisovanie webhookov