LIVE · AUDIT-KEDJA · EU-VÄRD
SYSTEM · 99,99 % DRIFTSTID
v 1.0 ↗ TILLVERKAT I EU

Koncept

Vad en Session, Evidence-rad och Audit Chain faktiskt är, med så få ord som möjligt. Läs det här en gång så blir API-referensen begriplig.

Organisation

Den översta tenanten. En organisation motsvarar ett kundkonto. Varje annan resurs (sessioner, bevis, revisionshändelser, användare) är begränsad till en Org via row-level security på de underliggande Postgres-tabellerna. En bugg i applikationskoden kan inte korsa tenantgränser — databasen vägrar frågan.

En Org har: medlemmar (användare med rollbaserad åtkomst), branding (logotyp / färger / PDF-sidfot), en faktureringsprenumeration, valfri KYB-data om juridisk person, valfri SSO-konfiguration och en lagringspolicy.

Medlem, Roll, Behörighet

En Medlemskap är kopplingen mellan en User och en Org. En användare kan ha medlemskap i flera organisationer och växla mellan dem (den aktiva organisationen följer med som en JWT-claim).

Varje Org seedar fyra systemroller vid skapandet:

  • org_admin — full kontroll. Fakturering, medlemmar, branding, lagring.
  • inspector — kan köra inspektioner, fånga bevis, signera rapporter.
  • observer — skrivskyddad åtkomst till sessioner + revisionsdata.
  • auditor — skrivskyddad åtkomst plus behörighet att verifiera kedjan.

Org-administratörer kan skapa anpassade roller genom att sätta samman behörighetskatalogen. Behörigheter slug-kontrolleras i view-lagret + korskontrolleras av RLS i DB-lagret.

Session

En inspektion. Faktureringsenheten (du betalar per stängd session) och bevisenheten (en revisionskedja är per session, inte per organisation).

En session har: en operatör (din teammedlem som startade den), en eller flera deltagare (fältanvändaren, plus valfria observatörer), samtyckesstatus, valfri GPS-position, valfria anteckningar, en revisionskedja och — när den stängts — TSA-förankrade tidsstämpeltokens.

Deltagare

En person i en session. Det finns en operatör per session och minst en fältanvändare; valfria ytterligare observatörer stöds. Fältanvändare ansluter via en engångssignerad URL (inget konto krävs); operatörer + observatörer är medlemmar i Org:en.

Bevis

Ett fångat bevis under en session. Typer:

  • snapshot — stillbild från fältanvändarens kamera.
  • annotation — teckning ovanpå en stillbild eller whiteboard.
  • whiteboard — Excalidraw-canvas i sessionen exporterad som PNG + state.
  • clip — kort videosegment.
  • document — uppladdad fil (används av chattlagret för PDF-för-signering).

Varje Evidence-rad har en SHA-256 av sitt binära innehåll, lagrad i revisionskedjan. Manipulation av filen i efterhand får verifieringen att misslyckas.

Revisionskedja

Den kryptografiska ryggraden. Varje händelse i en session — sessionsskapande, samtyckesgivande, GPS-registrering, bevisfångst, annotering, whiteboard-sparning, signatur, sessionsslut — avger en AuditEvent rad med:

{
  "session": "<uuid>",
  "sequence": N,
  "occurred_at": "<iso8601>",
  "kind": "evidence.snapshot_added",
  "actor": { "user": <id|null>, "participant": <id|null> },
  "payload": { /* event-specific */ },
  "prev_hash": "<sha256 of previous event>",
  "hash": "<sha256 of canonical_json of this event>"
}

Den första händelsen använder prev_hash = "0" * 64 (genesis). Varje efterföljande händelse använder föregående händelses hash som prev_hash och ökar sequence med 1. Ett Postgres-advisory-lock serialiserar skrivningar per session; en append-only-trigger blockerar UPDATE + DELETE på tabellen.

TimestampToken (TSA-förankring)

Vid sessionsslut (och vid operatörsutlöst "stämpla nu") skickas det aktuella kedjehuvudet till tre oberoende tidsstämplingsmyndigheter:

  • YodaLedger — Tezos-blockkedjeförankring. ~15–20 minuters finalitet. Asynkron; vi får en callback när blocket bekräftas.
  • FreeTSA — RFC 3161-tidsstämpel. Synkron; token returneras omedelbart. Utbytbar till en betald QTSP (DataSure) för eIDAS art. 42-efterlevnad.
  • OpenTimestamps — Bitcoin-förankring via OpenTimestamps kalenderprotokoll. Asynkron; uppgraderingsvägen körs på en Celery-sweep.

Tre är avsiktligt — om någon TSA försvinner förankrar de andra två fortfarande kedjan. En granskare kan verifiera mot vilken som helst av dem självständigt med publika block explorers / verifierings-endpoints.

Signatur (SES / AES / QES)

Tre eIDAS-nivåer, alla på samma revisionsrapports-PDF:

  • SES (Enkel elektronisk signatur) — revisionskedje-uppbackad, inget signeringscertifikat. Lämplig för interna register.
  • AES (Avancerad elektronisk signatur) — identitetsbundet signeringscertifikat, PAdES B-T-förankrat. Lämplig för de flesta B2B-kontrakt.
  • QES (Kvalificerad elektronisk signatur) — högsta eIDAS-nivån, juridisk motsvarighet till en handskriven underskrift i hela EU. Kräver KYB-verifiering av den utfärdande organisationen.

Kampanj (valfritt)

En logisk gruppering av sessioner för batchad rapportering — "Motorskador Q2 2026" eller "Överlämningsfel plats A". Sessioner kräver ingen kampanj; det är en rapporteringshjälp.

Webhook

En kundregistrerad URL som tar emot HMAC-signerade event-POST:ar. Event-typer: session.created, session.completed, participant.joined, participant.left, evidence.added, recording.ready, audit.anchored, signature.completed, plus en webhook.test för leveransverifiering.

Signatur: Stripe-stil t=...,v1=... header med HMAC-SHA256 över <timestamp>.<body>. SDK:ns constructEvent() -hjälpare verifierar i konstant tid med 5 minuters klockskev-tolerans.