Egy bizonyítékrekord olvasása
Egy drill pontosan egy rekordot állít elő, amit a bizonyítéknaplóhoz fűzünk. Ez a termék — a teszt csak az eszköz —, tehát megéri úgy elolvasni egyet, hogy közben nem kell a sémát nézegetni.
{ "adapter": { "digest": "sha256:4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c", "name": "postgres", "protocol": "probavi-adapter/0", "version": "0.1.0" }, "backup": { "checksum": "sha256:9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f", "created_at": "2026-07-30T01:58:02.000Z", "kind": "pgdump", "size_bytes": 565248 }, "checks": [ { "detail": "accepting connections", "name": "service_healthy", "ok": true }, { "detail": "100000 rows (min 100000)", "name": "row_count:orders", "ok": true } ], "drill": { "config_hash": "sha256:7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d", "name": "prod-orders-db", "pitr_target": "2026-07-30T14:32:00.000Z" }, "env": { "arch": "amd64", "host_id": "3f7a9c2e5b1d8e04", "os": "linux", "probavi_digest": "sha256:1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d", "probavi_version": "0.1.0" }, "error": null, "outcome": "pass", "prev_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "sandbox": { "params": { "image": "postgres:16", "memory": "2GiB" }, "provider": "docker" }, "schema": "probavi-evidence/2", "seq": 1, "sig": { "alg": "ed25519", "key_id": "56475aa75463474c", "sig_b64": "/f2ahJgj08qDVSvbTIZ/+XI7IfkCavp0WfS7ETIezC+E2PMzFzEmX/G8d4d+S42Q9ZegQDU8aMKJTBb/gS5KDQ==" }, "timings_ms": { "engine_ready": 1166, "provision": 1170, "restore": 190, "total": 2840, "transfer": 110, "validate": 61 }, "ts": "2026-07-31T02:00:11.482Z"}Valódi rekord a formátum közzétett példanaplójából, olvashatóság kedvéért újratördelve — a lemezen egyetlen kanonikus sor, és az aláírás arra a formára vonatkozik.
Aláírva ezzel:03a107bff3ce10be1d70dd18e74bc09967e4d6309ba50d5f1ddc8664125531b8
Mit mond az egyes részek
Szekció neve “Mit mond az egyes részek”Hol áll a láncban. A seq a pozíció, a prev_hash az előtte lévő rekord
SHA-256 lenyomata, a ts pedig az, amikor a drill befejeződött. A napló első
rekordja csupa nulla prev_hash-t hord, mert nincs elődje. Változtass meg
bármelyik rekordot, és utána minden láncszem ellenőrzése megbukik — ettől lesz
a napló a gyakorlatban is csak bővíthető, nem pusztán szándék szerint.
Mi volt a drill célpontja. A drill mező nevezi meg, és hordozza a
használt konfiguráció lenyomatát, így két rekordról eldönthető, hogy ugyanaz a
drill állította-e elő őket, vagy egy drill, amit közben valaki átírt. Ahol
időpontra visszaállítást kértek, a célidőpont is bekerül mellé.
Miből állítottunk vissza. A backup rögzíti a forrásfajtát, az archívum
méretét, az ellenőrzőösszegét, és azt, mikor készült. A készítés ideje az a
mező, amit elsőként érdemes elolvasni, ha egy siker túl szépnek tűnik: az a
rekord, ami egy három hónapos archívumról bizonyítja, hogy visszaállítható,
igaz állítás egy olyan mentésről, amire senkinek nem kellene támaszkodnia.
Hova állítottuk vissza. A sandbox megnevezi a szolgáltatót és a kapott
paramétereket — az image-et, a memóriakorlátot —, szó szerint rögzítve. Az
adapter megnevezi az adaptert, a verzióját, az általa beszélt
protokollverziót, és a digest-et: a mag által indított adapter futtatható
állományának SHA-256 lenyomatát. A verzió és a digest nem ugyanaz a tény: a
verzió olyan szám, amit az adapter magáról jelent, tehát két különböző build
oszthat egyet — a digest az, ami megkülönbözteti őket. Együtt ezek teszik egy
visszaállítási időt egy másikkal összehasonlíthatóvá: azonos image, azonos
korlátok, azonos adapter-build — vagy a két szám nem ugyanazt méri.
Mi történt. Az outcome a drill ítélete, az error pedig az indokot
hordozza, ha van. A checks minden ellenőrzést felsorol névvel, az
eredményével és egy rövid részlettel — a sorok talált számával és a korláttal,
amihez mérték, nem pusztán annyival, hogy átment.
Mennyi ideig tartott. A timings_ms fázisokra bontja a drillt: a sandbox
létrehozása, az archívum átvitele, maga a visszaállítás, a motor elindulására
várakozás, és az ellenőrzés. A visszaállítási fázist szándékosan az
ellenőrzésektől külön mérjük, hogy az a szám, amit a helyreállítási célidődhöz
hasonlítasz, ne attól legyen nagyobb, hogy mennyi SQL-t futtatsz utána.
Hol futott. Az env rögzíti az operációs rendszert, az architektúrát, egy
állandó gépazonosítót, a Probavi verzióját, és a probavi_digest-et: a
rekordot kiíró probavi futtatható állomány SHA-256 lenyomatát. Elég ahhoz,
hogy két, drilleket futtató gépet megkülönböztess, hogy egy időbeli változást
megmagyarázz, és hogy megmondd, melyik build állította elő a bizonyítást; nem
elég semmi máshoz, mert a drillről semmi nem hagyja el a gépet. Bármelyik
digest null, ha a fájlt nem lehetett elolvasni — egy digest megéri, hogy
rögzítsük, de soha nem éri meg, hogy megbuktasson egy drillt.
Az aláírás. A sig hordozza az algoritmust, a kulcsazonosítót és magát az
aláírást, a rekord kanonikus egysoros formája fölött.
Mit bizonyít az ellenőrzés
Szekció neve “Mit bizonyít az ellenőrzés”Egy napló ellenőrzéséhez a fájl kell és egy publikus kulcs — nincs hálózat, nincs licenc, és még Probavi-telepítés sincs, mivel a formátumhoz önállóan kiadott ellenőrző tartozik.
Amit megállapít, az pontos: hogy ezeket a rekordokat annak a kulcsnak a
birtokosa állította elő, és azóta nem változtak. Minden aláírás érvényes, és
minden prev_hash egyezik azzal a rekorddal, amire mutat — tehát a napló
közepéből semmit nem szerkesztettek, rendeztek át vagy vettek ki. Ez pontos
megfogalmazás, és egyetlen fajta eltávolítást hagy az alábbi szakaszra.
Az egyetlen eltávolítás, amit a fájl nem mutat meg
Szekció neve “Az egyetlen eltávolítás, amit a fájl nem mutat meg”A kivétel a napló vége. Ha a legfrissebb rekordokat töröljük, ami marad, az egy rövidebb napló: a sorszámozása továbbra is 1-nél kezdődik, a lánca töretlen, így a csak a fájlt olvasó ellenőrző VALID választ ad — helyesen, mert pusztán ebből a fájlból semmi nem tudja megkülönböztetni a levágott naplót attól, amelyik egyszerűen rövidebb. A következő drill a megrövidült láncra fűz tovább, tehát az eltávolítás utólag sem hagy nyomot.
Ezt egyetlen, a fájlon kívül tartott érték zárja le. Minden ellenőrzés kiírja a
head értékét: a legmagasabb elért seq-et, mellette annak a rekordnak a
tárolt sorára számított SHA-256 értéket, <seq>:sha256:<hex> alakban. Az egyik
futás által kiírt head-et őrizd meg, és add át a következőnek --anchor néven.
Az a napló, amelyik ezt a sort változatlanul hordozza, azóta nőtt — ez a
szokásos eset, és a válasz ugyanaz, amit a fájl horgony nélkül is adott volna.
Amelyik e seq előtt véget ér, abból a végéről hiányoznak rekordok. Amelyikben
az adott seq-en álló sor másra hasheelődik, azt levágták, majd újra
megnövesztették — elég hosszú, és ott hibás, ahol számít. Az utóbbi kettő
INVALID, kilépési kód 2: a horgonyánál rövidebb napló nem az a napló, amelyikről
a horgony készült, és ez ugyanaz a megállapítás, mint egy belülről kivett rekord.
A horgony ereje teljes egészében azon múlik, hol tartják, ezért oda tedd, ahová
a napló írója nem ér el — egy ticketbe, egy levélbe, egy olyan forráskódba tett
commitba, amelybe a drill gépe nem írhat, vagy egy probavi push fogadóba,
amelyik megőrzi, amit kapott. A Probavi egyiket sem tartja meg: kiírja az
értéket, és ennyi. Aláírni sem érdemes, mert a támadó, aki ellen ez a formátum
készült, épp az aláíró kulcs birtokosa.
Ez semmit nem mozdít a formátumon. Nem kerül bele mező, nem íródik alá semmi
további, és a rekordok továbbra is probavi-evidence/2 szerintiek — a horgony
az ellenőrzés bemenete, és nélküle a fájl és a publikus kulcs továbbra is
elegendő mindahhoz, amit maga a lánc bizonyítani tud.
Mit nem bizonyít, szándékosan
Szekció neve “Mit nem bizonyít, szándékosan”Az ellenőrzés a rekordról szóló állítás, nem a helyreállítási helyzetedről. Nem mondja meg, hogy a mentés a jó adatbázisról készült, hogy az ellenőrzések a jó ellenőrzések voltak, vagy hogy a visszaállítási idő a célidődön belül van. Egy tökéletesen érvényes aláírás egyetlen healthcheckből és semmi más állításból álló drill rekordján azt bizonyítja, hogy a drill megtörtént, és beszámol arról a kevésről, amit állított.
A két digest szűkebb, mint amilyennek látszik, és a specifikáció ezt ki is mondja ahelyett, hogy feltételezésre hagyná. Mindkettő egy fájl lenyomata, amit közvetlenül a futtatása előtt olvastunk be — tehát azokat a bájtokat nevezi meg, amiket a Probavi kiválasztott, nem azt bizonyítja, hogy azok a bájtok voltak a végrehajtott utasítások. Egy fájl, amit a lenyomat és az indítás között kicseréltek, rögzítetlenül maradna. Ennek az ablaknak a bezárása a futó folyamat saját image-ének olvasását jelentené, ami nem létezik minden platformon, amit a Probavi támogat — így a rekord azt a szűkebb állítást teszi, amit meg tud tartani.
Ez nem megkerülendő korlát. Ez a munkamegosztás: az aláírás teszi a történetet megbízhatóvá, és az általad választott ellenőrzések döntik el, hogy a történet mit ér.