Arkitektur

Bygget for nulltillit, laget for komponerbarhet

Arkitekturen i MindooDB skiller synkroniseringsoppgaven (å flytte krypterte byte) fra applikasjonsoppgaven (å dekryptere og tolke data). Denne ene designbeslutningen gjør klient-server-, peer-to-peer-, relay- og mesh-topologier mulige — alle med samme protokoll og samme kode.

MindooDB-arkitektur: nøklene blir liggende på enhetene, krypterte data flyter gjennom hvilken som helst nettverkstopologi til en lagring som ikke kan dekryptere dem
For beslutningstakere

Hva denne arkitekturen gir deg

Vurderer du MindooDB for teamet ditt, er det avgjørende arkitekturspørsmålet: kan jeg innføre dette gradvis uten å låse meg? Svaret er ja. MindooDB er laget for gradvis innføring — start rent lokalt, legg til klient-server-synkronisering når det passer, og slå på P2P- eller relay-topologier senere. Hvert trinn bruker samme ContentAddressedStore-grensesnitt, så et bytte av driftsmodell er en konfigurasjonsbeslutning og ingen omskriving av kode.

Innføringsarbeid

Timer for rent lokal drift. Dager for klient-server-synkronisering (2 auth- + 3 synkroniseringsendepunkter). Trinnvis for P2P, relay eller Bloom-filter-optimaliseringer — helt uten protokollendringer.

Sikkerhetsnivå

Tre uavhengige beskyttelseslag: AES-256-GCM under lagring, RSA per bruker under overføring, TLS på linjen. Serverne ser aldri klartekst. Et fullstendig serverinnbrudd gir bare chiffertekst og offentlige nøkler.

Enkel drift

Ingen brukerkontoer på serversiden, ingen passordlagring, ingen øktdatabaser. Serveren er et relay for krypterte blobber. Brukeradministrasjonen skjer på klientsiden gjennom kryptografiske nøkkelpar.

Kjernearkitektur

Tenants, brukere og tillitskjeden

En MindooDB-tenant står for en organisasjon eller et team. Tenants opprettes helt på klientsiden — ingen registrering på serveren er nødvendig. Den som oppretter tenanten, blir administrator, og administratorens Ed25519-signeringsnøkkel er tillitsroten. Hver brukerregistrering i katalogen signeres med denne admin-nøkkelen, og både klienter og servere kontrollerer signaturene før de stoler på en brukers offentlige nøkkel. Tillit etableres altså gjennom kryptografiske bevis, ikke gjennom autentisering på serveren.

Oppbygningen av en tenant

Hver tenant inneholder en katalogdatabase (brukerregister, kun for administratorer), flere applikasjonsdatabaser og nøklene som styrer tilgangen.

  • Katalogdatabase — Admin-signerte brukerregistreringer, gruppemedlemskap, innstillinger
  • Applikasjonsdatabaser — Opprettes ved behov (tenant.openDB("contacts"))
  • Dokumenter — Automerge-CRDT-er med signert, kryptert append-only-historikk
  • Vedlegg — Fillagring i biter (256 KB), kryptert og deduplisert
Nøkkelhierarki

Tillit flyter fra admin-nøkkelen via katalogen til de registrerte brukerne. Hver nøkkeltype har sitt bestemte formål:

  • Admin-signeringsnøkkel (Ed25519) — Tillitsrot; signerer katalogoppføringer
  • Admin-krypteringsnøkkel (RSA-OAEP) — Krypterer brukernavn av personvernhensyn
  • Brukernes signeringsnøkler (Ed25519) — Beviser hvem som står bak dokumentendringer
  • Brukernes krypteringsnøkler (RSA-OAEP) — Beskytter den lokale KeyBag-lagringen
  • Standard tenant-nøkkel (AES-256) — Krypterer dokumenter for alle medlemmer
  • Navngitte nøkler (AES-256) — Finmasket tilgang for enkelte brukere
Hvordan delene spiller sammen
En bruker kan tilhøre flere tenants; hver tenant inneholder flere databaser og kan synkronisere med én eller flere MindooDB-servere; flere brukere deler en tenant når de har fått tilgang; en app lagrer dataene sine i én eller flere databaser og fungerer online som offline; virtuelle visninger leser på tvers av databaser, tenants og lokale eller eksterne kilder
En bruker kan tilhøre flere tenants, og flere brukere kan dele én tenant når administratoren gir dem tilgang. Hver tenant inneholder flere databaser og synkroniserer med én eller flere servere. Apper lagrer dataene sine i én eller flere databaser og fortsetter å virke offline. Virtuelle visninger leser på tvers av databaser, tenants og lokale eller eksterne kilder.
Arkitekturen i korte trekk
MindooDB-arkitektur: klientene holder nøklene lokalt, krypterer og signerer alle data og synkroniserer krypterte oppføringer med server eller peers som ikke kan dekryptere dem
Klientene krypterer og signerer før synkronisering. Serverne lagrer chiffertekst. Synkroniseringen utveksler bare de krypterte oppføringene hver side mangler.
Grunnleggende abstraksjon

Det innholdsadresserte lageret

I sentrum av fleksibiliteten i MindooDB står grensesnittet ContentAddressedStore. Hvert lager — enten det ligger på lokal disk, i minnet eller bak en nettverksforbindelse — implementerer det samme grensesnittet. Synkroniseringsmetodene pullChangesFrom() og pushChangesTo() godtar hvilket som helst ContentAddressedStore, og de virker derfor identisk uansett om motparten er et lokalt lager, en ekstern server over HTTP eller Iroh, eller en annen klient over Iroh.

Nettopp denne designideen gjør hver topologi mulig: fordi nettverkslagre implementerer samme grensesnitt som lokale lagre, blir synkronisering komponerbar. Det underliggende lageret til en server kan selv være et eksternt lager (lagerkjeding). Et relay kan videresende krypterte oppføringer uten å dekryptere dem. En peer kan kjøre samme synkroniseringslogikk som en server. Topologien er en driftsbeslutning, ikke en kodeendring.

Append-only-oppføringer

Hver dokumentendring, hvert øyeblikksbilde og hver del av et vedlegg lagres som en uforanderlig oppføring med egen ID og innholdshash. Oppføringer endres eller slettes aldri — det garanterer et komplett revisjonsspor.

Kryptografisk kjeding

Hver oppføring viser til foreldreoppføringene sine med ID (det gir en DAG) og er signert av den som laget den. Å tukle med en oppføring bryter kjeden — integriteten kan kontrolleres på hvert punkt.

Automatisk deduplisering

Oppføringer identifiseres med id og dedupliseres med contentHash (SHA-256 av den krypterte payloaden). Identisk innhold fra flere kilder lagres bare én gang.

Innholdsadressert synkroniseringsflyt
Det lokale lageret utveksler oppførings-ID-er med det eksterne lageret, henter manglende oppføringer og dedupliserer etter innholdshash
Avstemming først over metadata: utveksle ID-er for å finne det som mangler, og overfør deretter bare de manglende oppføringene. Fungerer identisk for klient-server-, P2P- og relay-topologier.
Synkroniseringsprotokoll

Start enkelt, optimaliser senere

Synkroniseringsprotokollen tilbyr tre veier som deler de samme endepunktene og den samme oppføringsmodellen. Baseline-synkronisering er den enkleste: send de oppførings-ID-ene du kjenner, få metadata om det du mangler, hent disse oppføringene. Det virker for datamengder i alle størrelser og er det anbefalte utgangspunktet. Optimalisert synkronisering legger til cursorbasert skanning og Bloom-filter-sammendrag for større datamengder — begge forhandles fram under kjøring via capability discovery og er dermed usynlige for applikasjonskoden. Dense sync bruker den kausale materialiseringsplanleggeren og overfører bare de oppføringene som trengs for den nyeste dokumenttilstanden — det beste øyeblikksbildet pluss de endringene det ikke dekker. Historiske oppføringer hoppes over, og vedlegg kommer senere. Ideelt for førstegangsoppsett på mobil over forbindelser med begrenset båndbredde.

Protokollgarantier

Disse invariantene gjelder i alle driftstopologier — klient-server, P2P, relay-kjeder og mesh:

  • Fullstendighet — Etter en full synkroniseringsrunde kjenner klienten metadataene til hver ekstern oppføring
  • Idempotens — Hvert endepunkt kan kalles gjentatte ganger uten sideeffekter
  • Rekkefølgeuavhengighet — Oppføringer kan komme i vilkårlig rekkefølge; CRDT-ene sørger for konvergensen
  • Deduplisering — Identiske oppføringer fra flere kilder lagres bare én gang
Ytelsesoptimalisering

For datamengder over noen titusen oppføringer holder to teknikker synkroniseringen rask:

  • Cursor-skanning — Bla gjennom eksterne metadata side for side i stedet for å sende store ID-lister. Størrelsen på forespørselen er konstant uansett hvor stort lageret er.
  • Bloom-filter-sammendrag — Last ned en kompakt probabilistisk mengderepresentasjon og forhåndsfiltrer ID-er med den. Fjerner 90-99 % av de eksakte eksistenssjekkene.
  • CRDT-øyeblikksbilder — Jevnlige øyeblikksbilder hindrer at ytelsen faller når lange dokumenthistorikker må spilles av på nytt.
  • Dense sync — Overfør bare det nyeste øyeblikksbildet og de endringene det ikke dekker, per dokument, uten historikk og vedlegg. Les mer →
Autentisering og tilbakekalling

Hver synkroniseringsoperasjon krever autentisering via challenge-response: klienten signerer en challenge fra serveren med sin Ed25519-nøkkel, og serveren utsteder et kortlevd JWT. Tilbakekalling håndheves på to punkter — når challengen genereres og når tokenet valideres — så en tilbakekalt bruker er utestengt umiddelbart, også midt i en økt. Verken passord eller tokens lagres på serveren. Samme challenge og samme JWT gjelder når serveren nås over Iroh: ticketen erstatter adressen, ikke kontrollen. En forbindelse fra enhet til enhet har ingen JWT — enheten som mottar, autoriserer den som ringer selv.

Driftstopologier

Samme protokoll, hvilken som helst nettverksform

Fordi synkroniseringen arbeider på krypterte oppføringer og bruker samme ContentAddressedStore-grensesnitt overalt, kan enhver node delta i synkronisering uten å dekryptere data. En relay-server lagrer og videresender oppføringer den ikke kan lese. En regional cache leverer oppføringer til klienter i nærheten uten å trenge nøkler. Tillitsgrensen ligger på nøkkelnivå, ikke på nivået til nettverkstopologien.

Klient-server

Standard oppsett med én sentral server. Enklest å sette opp og drifte. Serveren validerer brukere via katalogen, lagrer krypterte oppføringer og synkroniserer med de tilkoblede klientene. HTTP er standarden. En server uten offentlig URL kan i stedet lytte på Iroh og nås med en iroh:-ticket — uten DynDNS, portvideresending eller sertifikat.

Protokoll for nettverkssynkronisering →

Peer-to-peer

To enheter i samme tenant synkroniserer direkte over Iroh (QUIC), uten en MindooDB-server i veien. Innfødte klienter prøver først en direkte vei og faller ellers tilbake på et relay; en nettleserfane går alltid via et relay. Enheten som mottar, sjekker signaturer og tilgangsregler selv, fordi en peer ikke utsteder noen vitnekvittering. Samme pullChangesFrom/pushChangesTo-API som ved klient-server.

P2P-synkronisering over Iroh →

Relay og lagerkjeding

Data flyter gjennom noder som ikke kan dekryptere dem. En sykehusserver synkroniserer pasientjournaler mellom klinikker uten å lese dem. En passthrough-node videresender forespørsler til en origin-server, for eksempel for edge-caching eller klare tilgangsgrenser.

Topologier sammenlignet
Topologi Når den passer Infrastruktur som trengs Hovedfordel
Klient-server Standard utgangspunkt; pålitelig synkronisering hele tiden Én server + klienter (HTTP eller Iroh) Enklest oppsett
Peer-to-peer Synkronisering fra enhet til enhet, uten MindooDB-server i veien Klienter + Iroh (relay når NAT blokkerer) Ingen server i veien
Relay Distribusjon via noder du ikke stoler på Relay-server (uten nøkler) Sikker datadistribusjon
Lagerkjede Edge-caching, geografisk distribusjon Origin + edge-noder Lavere latens
Mesh Robust konvergens mellom mange peers Flere peers Ingen enkelt feilpunkt
Hybrid Server for pålitelighet, peers mens den er nede Server + direkte peer-lenker Det beste av begge
Synkroniseringsmoduser
Klient-server-, peer-to-peer- og hybridtopologier med samme innholdsadresserte synkroniseringsprotokoll
Alle topologier bruker samme ContentAddressedStore-grensesnitt og samme synkroniseringsprotokoll. Å bytte topologi er en driftsbeslutning, ikke en kodeendring.
Varighet

Krasjsikkerhet og dataintegritet

MindooDB legger krypterte, innholdsadresserte oppføringer direkte i filsystemet. Dermed har lageret full kontroll over commit-rekkefølge, gjenoppretting etter krasj og deduplisering, uten å være avhengig av en innebygd databasemotor som SQLite eller LevelDB.

Skriveprotokoll

Hver filskriving følger en atomisk fremgangsmåte: skriv til en midlertidig fil, fsync, atomisk omdøping, fsync av den overordnede katalogen. Lesere ser aldri en halvferdig tilstand. Commit-rekkefølgen (først payload, så metadata, så indekssegment) sikrer at en oppføring først blir synlig når payloaden ligger trygt på disken.

  • Krasj mellom payload og metadata — Den foreldreløse payloaden er harmløs
  • Krasj mellom metadata og indeks — Oppføringen er committet; indeksen bygges opp igjen ved oppstart
  • Krasj under compaction — En utdatert indeks oppdages og bygges opp igjen fra de autoritative oppføringsfilene
Gjenoppretting ved oppstart

Ved oppstart forsøker lageret først rask gjenoppretting: last metadata-øyeblikksbildet, spill av de inkrementelle segmentene og valider mot de autoritative oppføringsfilene. Er noe utdatert eller inkonsistent, faller det tilbake på en full gjenoppbygging fra disk — transparent og uten tap av data.

  • Indekser i minnet — O(1)-punktoppslag, cursor-skanning med binærsøk, dokumentavgrensede spørringer
  • Segment-compaction — Fletter inkrementelle metadata til friske øyeblikksbilder og holder oppstarten rask
  • Source of truth — Oppføringsfilene på disken er alltid autoritative; indeksfiler er ren akselerasjon og kan slettes uten risiko

Hele gjennomgangen av implementasjonen står i dokumentasjonen om on-disk-lageret.

Datamodellering

Organisere data for vekst

Append-only-arkitekturen i MindooDB betyr at data vokser over tid. Siden hver endring bevares for revisjonssporet, er det verdt å planlegge for denne veksten. Det viktigste verktøyet er sharding på databasenivå: del data på egne databaser etter tidsrom, kategori, tilgangsnivå eller geografi. Hver database synkroniserer for seg, så du styrer nøyaktig hvilke data som flyter hvor.

Sharding-strategier
  • Etter tid — Års- eller månedsdatabaser holder synkroniseringen av aktive data rask og bevarer historikken
  • Etter kategori — Egne databaser per dokumenttype, prosjekt eller forretningsområde
  • Etter tilgang — Skill data etter sikkerhetsnivå, slik at ulike team synkroniserer ulike delmengder
  • Etter geografi — Én database per region for krav til datalagringssted

Mønstre for datamodellering →

Spørringer og indeksering

Dokumentene er kryptert under lagring, så spørringer på serversiden er utelukket. I stedet tilbyr MindooDB inkrementell indeksering på klientsiden:

  • Cursorbasert behandlingiterateChangesSince(cursor) behandler bare dokumenter som er endret siden forrige kjøring
  • Pluggbare indeksere — Send endringer videre til FlexSearch, Lunr eller en egen indeks
  • Virtuelle visninger — Regnearklignende kategorisering med sortering og aggregering, på tvers av flere databaser eller tenants

Dokumentasjon om indeksering →

Multi-tenant-arkitektur

Tenant-isolasjon og samarbeid på tvers av tenants

Tenants er kryptografisk isolert som standard — hver tenant har egne krypteringsnøkler, en egen brukerkatalog og sitt eget sett med databaser. Samarbeid på tvers av tenants er mulig ved å dele enkelte databaser eller navngitte krypteringsnøkler mellom tenants, samtidig som administrasjonen holdes atskilt per tenant.

Isolasjonsgarantier
  • Hver tenant har egne krypteringsnøkler — ingen delte hemmeligheter
  • Egne brukerkataloger med egne admin-nøkler
  • Data er isolert som standard; deling krever eksplisitt nøkkeldistribusjon
  • Å tilbakekalle en bruker i én tenant påvirker ikke andre tenants
Mønstre på tvers av tenants
  • Del enkelte databaser mellom tenants med navngitte nøkler
  • Virtuelle visninger kan samle data på tvers av tenant-grenser
  • Hver tenant beholder egen administrasjon og egen tilbakekalling
  • Nyttig for forsyningskjeder, partnerorganisasjoner og felles prosjekter

Mønstre på tvers av tenants →

Ærlige avveininger

Dette bør du vite før du tar det i bruk

Hver arkitektur innebærer avveininger. Ende-til-ende-krypteringen og append-only-designet i MindooDB gir sterke garantier for sikkerhet og etterprøvbarhet, men de kommer med begrensninger du bør kjenne fra starten.

Grenser for tilbakekalling

Å tilbakekalle en bruker blokkerer all videre synkronisering og avviser brukerens framtidige endringer. Data som alt er synkronisert til enheten, er likevel fortsatt lesbare — ingen systemer kan garantere sletting på en enhet som aldri kobler seg til igjen. Mottiltak: bruk navngitte nøkler for sensitive dokumenter (mindre skadeomfang), og roter nøklene når brukere slutter. Haven Enterprise legger fjernsletting på enheten med admin-signatur til de samme governance-policyene: tenanten fjernes fra en stjålet eller forlatt enhet neste gang den kobler seg til.

Ingen spørringer på serversiden

Fordi data krypteres før de forlater klienten, kan serveren ikke kjøre spørringer. All spørring skjer på klientsiden, gjennom inkrementell indeksering, virtuelle visninger eller pluggbare søkeindekser. Det er en bevisst avveining: konfidensialitet foran bekvemmelighet på serversiden.

Kompleks nøkkelhåndtering

Flere nøkler per bruker (signering, kryptering, navngitte symmetriske nøkler) må distribueres sikkert. Mottiltak: ett enkelt passord låser opp alle nøkler via en KDF med ulike salt. KeyBag gir én samlet nøkkellagring. Flyten med join-forespørsel og -svar håndterer nøkkelutvekslingen for nye brukere. Haven Enterprise automatiserer det løpende arbeidet: admin-signerte policyer for nøkkeldistribusjon forsyner brukere og grupper med nøkler — og tilbakekaller dem igjen — pakket per mottaker, og hver klient avstemmer sin KeyBag ved neste synkronisering.

Vekst med append-only

Data vokser fordi revisjonssporet bevares. Mottiltak: sharding på databasenivå begrenser veksten per synkroniseringsenhet. CRDT-øyeblikksbilder senker kostnaden ved avspilling. GDPR-purge (purgeDocHistory) er tilgjengelig når regelverket krever sletting.

I praksis
Haven - referanseklienten for denne arkitekturen

MindooDB Haven bruker disse byggeklossene i en nettleserbasert PWA: nøklene blir hos brukeren, apper kjører capability-basert i sandkasse, dessuten fleksible synkroniseringsmoduser og en ekte app-plattform. Raskere kommer du ikke til å oppleve MindooDB fra ende til ende.