Denník, kontrolné body a kotvy
Samotná pečať dokazuje, že riadok zodpovedá nejakej pečati. Denník dokazuje, že zodpovedá tej najnovšej: každá udalosť pečatenia pridá záznam do sentinel_ledger chránený MAC nad jeho auditnými poľami a plánovaný sentinel:checkpoint nové záznamy zloží do zreťazených kľúčovaných kontrolných bodov a najnovší publikuje do nakonfigurovaných kotiev.
Sentinel::ledger()->checkpoint(); // CheckpointResult or null
$report = Sentinel::ledger()->verify(); // LedgerReport
$report->clean();
$report->findings; // list<LedgerFinding>
Sentinel::ledger()->history($invoice); // list<LedgerRecord>
Sentinel::ledger()->head(); // the newest checkpoint
Sentinel::ledger()->anchors(); // ['cache']Záznamy denníka
- Pridávajú sa v tej istej transakcii ako udalosť pečatenia — sealed, resealed, acknowledged, baseline, rotated, deleted, unsealed — jedinečne pre (model, pečať, verzia), so súvislými verziami, ktoré prežijú zmazanie aj opätovné vytvorenie.
- Každý záznam má vlastný MAC nad identitou, verziou, udalosťou, kľúčom, MAC pečate, predošlým digestom, názvami zmenených atribútov, predošlým stavom, aktérom a dôvodom. Úprava ktoréhokoľvek auditného poľa je EntryInvalid.
- Len na pripájanie: aktualizácia či zmazanie LedgerEntry alebo Checkpoint cez Eloquent vyhodí LedgerIsAppendOnlyException — aj pri vypnutých udalostiach modelu.
- Nikdy sa nečistí — je to dôkaz. Vypnutím (SENTINEL_LEDGER=false) stratíte detekciu podstrčenia a návratu.
Kontrolné body
sentinel:checkpoint (predvolene každú minútu) zamkne najnovší kontrolný bod, vyberie dávku nepriradených záznamov v poradí id, zreťazí ich od predošlého rootu, vloží kontrolný bod s vlastným MAC (podpísaný aktuálnym kľúčom ledger.ring) a záznamy si priradí. Záznamy potvrdené neskôr sa pridajú do ďalšieho kontrolného bodu; súbežné behy a obete deadlockov sa opakujú. LedgerCheckpointed sa spustí po commite a kontrolný bod sa publikuje do kotiev.
use RoundlyConsulting\Sentinel\DataTransferObjects\CheckpointOptions;
use RoundlyConsulting\Sentinel\DataTransferObjects\LedgerVerifyOptions;
Sentinel::checkpoint(new CheckpointOptions(connection: null, batchSize: 500)); // one batch; null = nothing pending
Sentinel::verifyLedger(new LedgerVerifyOptions(entities: false)); // skip the per-entity head scan
Sentinel::verifyLedger(new LedgerVerifyOptions(manualAnchor: $payload)); // compare an AnchorPayload you kept
Sentinel::ledgerHead(); // ?CheckpointRecord, unverified
Sentinel::anchors(); // the configured anchor namesHistória jedného modelu
$entries = Sentinel::ledger()->history($invoice, 'financial', limit: 20); // list<LedgerRecord>, newest first
$entries = Sentinel::for($invoice)->history(); // the handle's seal
$entries = Sentinel::ledgerHistory($invoice); // flat formLedgerRecord má id, event, version, ring, keyId, changed, previousStatus, actorType, actorId, reason, occurredAt a checkpointId (null, kým nie je v kontrolnom bode). Záznamy sa čítajú tak, ako sú uložené — na ich kontrolu spustite verifyLedger().
Kotvy
Kotva ukladá najnovší kontrolný bod mimo databázy. Bez nej sa obnova celej databázy (vrátane denníka a kontrolných bodov) zo staršieho snapshotu ani zmazanie konca kontrolných bodov odhaliť nedá.
| Driver | Ukladá | Číta späť |
|---|---|---|
cache | put('{key}:{connection}', payload) natrvalo v anchor_drivers.cache.store — Redis, ktorý nie je databázou aplikácie. | áno |
filesystem | {path}/{connection}/{seq}.json + latest.json na anchor_drivers.filesystem.disk — ideálne objektové úložisko s object lock alebo verziovaním. | áno |
log | Log::channel()->info('sentinel.anchor', payload). | nie — len zápis; porovnáte cez sentinel:verify --ledger --anchor='<json>' |
| vlastný | Sentinel::extendAnchor() | podľa vás |
SENTINEL_ANCHORS=cache,filesystem
SENTINEL_ANCHOR_CACHE_STORE=anchor-redis
SENTINEL_ANCHOR_DISK=s3-lockedObsah (sentinel.anchor/1: connection, seq, root, at, ring, keyId, algorithm, mac) nesie MAC kontrolného bodu, takže zmenená kotva sa odhalí; podvrhnutá kotva, ktorá tvrdí, že je napred, spôsobí len planý poplach. Publikovanie prebieha po commite a bez záruky: zlyhanie spustí AnchorPublishFailed, zaloguje sa a ďalší beh publikuje znova do kotiev, ktoré zaostávajú. Vlastné kotvy nájdete v časti Rozšírenie.
Overenie denníka
$report = Sentinel::ledger()->verify(); // every connection, entity heads included
$report = Sentinel::ledger()->verify('tenant', entities: false, chunk: 5000);
$report->checkpoints; // checkpoints verified
$report->entries; // ledger entries verified
$report->anchorsChecked; // anchors compared
$report->findings; // list<LedgerFinding>
$report->clean();
$report->violations(); // findings except backlog and unreachable anchors
$report->has(LedgerFindingKind::AnchorAhead);
$report->throwIfViolated(); // LedgerIntegrityExceptionPre každé pripojenie v ledger.connections overenie kontroluje:
- Kontrolné body v poradí seq: súvislé (CheckpointGap), zreťazené (ChainBroken), s MAC od použiteľného kľúča kruhu denníka (CheckpointInvalid) a každý root prepočítaný nad jeho záznamami s kontrolou MAC každého záznamu (EntryInvalid, CheckpointMismatch).
- Kotvy: nedostupná (AnchorUnreachable), neplatný MAC či kľúč (AnchorInvalid), napred pred databázou (AnchorAhead), iný root pri tom istom seq (AnchorMismatch).
- Čakajúce záznamy: ich MAC, Backlog, ak sú záznamy staršie než ledger.backlog_warning_seconds stále neukotvené, a OrphanEntry pre záznam, ktorého checkpoint_id neukazuje na žiadny kontrolný bod.
- Hlavy entít (s entities): každý model, ktorého posledný záznam nie je tombstone, musí stále existovať (EntityDeleted) so svojím riadkom pečate (SealMissing) v danej verzii (SealRolledBack).
Každé zistenie okrem Backlog a AnchorUnreachable je porušenie a spustí LedgerIntegrityViolated. Dôkazy v denníku podpísané kľúčom, ktorý bol neskôr vyradený, sa stále overia; odvolané, čakajúce a neznáme kľúče nikdy.
Viac pripojení
Pečate, denník a kontrolné body žijú na pripojení každého zapečateného modelu. Ak ich máte na viacerých pripojeniach, spustite migrácie 0002–0004 na každom a uveďte ich:
'ledger' => ['connections' => [null, 'tenant_archive']],Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.