Härdning: kedjesvep i drift — och svepets första egna fynd
KEDJESVEPET. Verifieringen fanns men anropades bara vid tvist: ett brott kunde stå oupptäckt i åratal och upptäckas i sämsta tänkbara ögonblick. Nu går driften igenom varje kedja och varje försegling i varje organisation — POST /api/kedjesvep för arbetsledaren, `node server.mjs --kedjesvep` för nattlig cron utan server, med felkod vid brott så att larmet är gratis. Endpoint och svep delar EN implementation (kedjestatus): två implementationer av "är kedjan hel?" kommer att svara olika den dag det betyder något — det var T-13/T-14:s rot, tillämpad i förebyggande syfte. SVEPETS FÖRSTA FYND VAR PÅ RIKTIGT. Första körningen mot integrationsmiljön rapporterade TRE brott där testerna saboterat två. Det tredje var en bugg: leverantörshändelser bär `enhet: undefined`, och den kanoniska formen serialiserade nyckeln som null medan databasens rundresa släpper den. Skriv-digest och läs-digest skilde sig — varje leverantörshändelse bröt sin egen kedjelänk. Klienthändelser gick fria av en slump: JSON.parse kan inte producera undefined. Fixat vid roten: kanonisk form är nu exakt den form som överlever rundresan, inte en nästan likadan. Mekanismen fungerade precis som avsett — dag ett, mot sina egna upphovsmän. TRANSPORTEN. Säkerhetshuvuden på varje API-svar: nosniff, no-store (ett API vars svar är personuppgifter får inte bli en cacheträff), frame-ancestors 'none', no-referrer, HSTS. För stor kropp svarar 413 i stället för ett intetsägande 500. Kroppstak 4 MiB och batchtak 500 verifierade som redan på plats — bokfört, inte antaget. En skriptläxa på vägen: cron-svepets felkod är själva poängen, men under `set -e` dödade den testskriptet vid tilldelningen — felkoden måste fångas i samma andetag. Utgåva 3.4. API-specen dokumenterar svepet. TÜV-2-rapporten har bilaga A med samma-dags-härdningen, inklusive svepets eget fynd. 768 enhetstester, 224 integrationskontroller mot riktig Postgres, återställningsprov, genomgång 4/4, portalspärr, typkontroll och lint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
This commit is contained in:
@@ -193,3 +193,17 @@ retention, and must continue to be stated as such.
|
||||
---
|
||||
|
||||
*ALVA-DOC-0007 · Internal engineering review · Not endorsed by any inspection body*
|
||||
|
||||
---
|
||||
|
||||
## Appendix A · Post-audit hardening (same day)
|
||||
|
||||
Implemented after the examination closed, in response to §4 and the
|
||||
verdict's root-cause note:
|
||||
|
||||
| Measure | Detail |
|
||||
| --- | --- |
|
||||
| Chain sweep | `POST /api/kedjesvep` (supervisor/admin) verifies every chain and seal in the organisation; `node server.mjs --kedjesvep` does the same across all organisations nightly, exiting non-zero on any break. Verification existed but was only ever invoked at dispute time — a break could stand undetected for years. |
|
||||
| The sweep's first catch | On its first run against the integration environment, the sweep reported **three** breaks where the tests had sabotaged two. The third was real: supplier-protocol events carried `enhet: undefined`, which the canonical form serialised as `null` while the database round-trip drops the key — write-digest and read-digest differed, and every supplier event broke its own chain link. Client events escaped by accident (`JSON.parse` cannot produce `undefined`). Fixed at the root: canonical form now matches exactly what survives the round-trip. The examiner notes the mechanism worked precisely as intended — on day one, against its own authors. |
|
||||
| One implementation of verification | Endpoint and sweep share `kedjestatus()`. Two implementations of "is the chain intact?" will disagree the day it matters — the T-13/T-14 root cause, applied prophylactically. |
|
||||
| Transport hardening | `nosniff`, `no-store`, `frame-ancestors 'none'`, `Referrer-Policy: no-referrer`, HSTS on every API response; oversized bodies answer 413 instead of a generic 500. Body cap (4 MiB) and batch cap (500) verified as already present. |
|
||||
|
||||
Reference in New Issue
Block a user