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.
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.
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.
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.
Ingen brukerkontoer på serversiden, ingen passordlagring, ingen øktdatabaser. Serveren er et relay for krypterte blobber. Brukeradministrasjonen skjer på klientsiden gjennom kryptografiske nøkkelpar.
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.
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
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
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.
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.
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.
Oppføringer identifiseres med id og dedupliseres med contentHash (SHA-256 av den krypterte payloaden). Identisk innhold fra flere kilder lagres bare én gang.
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.
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
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 →
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.
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.
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.
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.
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.
| 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 |
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.
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
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.
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.
- 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
Dokumentene er kryptert under lagring, så spørringer på serversiden er utelukket. I stedet tilbyr MindooDB inkrementell indeksering på klientsiden:
- Cursorbasert behandling —
iterateChangesSince(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
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.
- 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
- 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
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.
Å 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.
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.
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.
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.
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.