Lavet i EU, og hvor dine data ligger
Hvor Nessie er bygget, hvor dine data ligger, og hvad du styrer, når du selv driver det.
Hvem bygger det, og under hvilken lov
Nessie bygges af UnlikeOtherAI s.r.o., et selskab registreret i Tjekkiet og underlagt tjekkisk lov.
Denne side beskriver, hvordan softwaren er bygget, og hvor den kører. Den er ikke en erklæring om compliance: Nessie har ingen sikkerhedscertificering, og intet her skal læses som en sådan. Hvilke personoplysninger der behandles, og på hvilket grundlag, fremgår af privatlivspolitikken, som er en separat side.
Hvor det hostede produkt kører
Nessie Cloud kører hos europæiske hostingudbydere — Scaleway, Hetzner og andre. Vi vælger den bedste tjeneste hos hver udbyder, så forskellige dele af produktet kan køre hos forskellige udbydere, alle sammen i Europa.
Alt, der er mere præcist end det — et bestemt sted, en by eller et datacenter — er med vilje ikke angivet her, fordi det ville blive forældet, uden at nogen lagde mærke til det.
Med selvhosting er valget dit
Hvor en selvhostet instans kører, er en driftsindstilling, ikke en produktindstilling. Vejen med én maskine er en Docker Compose-stack, som du placerer på en maskine, du selv vælger. I Terraform-træet til en administreret cloud er regionen et input helt uden standardværdi: intet her kan gættes, så intet her har en standardværdi, og databasen, objektlagerets bucket og tjenesterne følger alle den region, du angiver.
To strukturelle detaljer har betydning for samme spørgsmål. Køen og realtidstransporten er begge PostgreSQL — der er ingen Redis og ingen message broker i forløbet, så der er ikke noget tredje system at placere. Og objektlageret er S3-kompatibelt og ikke bundet til én leverandør; referenceopsætningen kører MinIO i en container på et privat netværk uden egen indgang udefra. De dele, der skal køre et sted, er databasen, objektlageret og de to Node-tjenester, og de kører alle dér, hvor du placerer dem. Hvordan du sætter det op, står på installationssiden.
Hvad Nessie gemmer — og hvad den bevidst ikke gemmer
Identiteten kopieres ikke
Med UnlikeOtherAI-login er det identitetsudbyderen, der administrerer og gemmer menneskers identitet — godkendelsesfaktorer, profiler, medlemskab af organisationer og teams samt invitationer. Nessie er en relying party, ikke endnu et identitetssystem. Det er lige så meget en beslutning om data som om arkitektur: en identitet, som Nessie aldrig gemmer, kan Nessie hverken lække, miste eller undlade at slette.
Det, tabellen users faktisk indeholder, er udbyderens stabile brugeridentifikator — nøglen, som alt andet slås op igennem — e-mailadressen, en ikke-autoritativ spejling af visningsnavn og avatar samt produktlokale felter (præferencer, pronominer og en tokenversion, der bruges til at tilbagekalde sessioner). Spejlingen findes kun, så et navn og et billede kan vises uden en forespørgsel pr. række, og den synkroniseres igen fra udbyderens verificerede claims ved login, ved teamskifte og ved fornyelse af sessionen. Intet opfindes: en person, som udbyderen ikke har angivet et navn for, vises med sin e-mailadresse, indtil det sker. Et password-hash findes kun for bootstrap-ejeren af en installation helt uden identitetsudbyder.
Det samme gælder strukturen. Én organisation hos udbyderen er én Nessie-organisation, bundet via udbyderens organisations-id; et team uden link opstrøms svarer 404 TEAM_NOT_LINKED i stedet for at falde tilbage på et lokalt gæt, og en live læsning af medlemslisten går til identitetsudbyderen og gemmer ikke noget.
To spejlinger er endnu ikke væk, og det ville være uærligt at give indtryk af andet. Navne på organisationer og teams gemmes stadig lokalt ved siden af bindings-id'erne, og lokale medlemsrækker giver stadig tilladelse til almindelige forespørgsler mellem synkroniseringerne. At fjerne begge er åbent, sporet arbejde i repositoriet og ikke noget, der allerede er færdigt.
Intet kommercielt
Den centrale faktureringstjeneste administrerer betalinger. Nessie gemmer ingen kunde, abonnement, faktura, pris, kreditsaldo, genopfyldningspolitik, betalingssamtykke, kontoudtog eller opsigelsesstatus hos betalingsudbyderen, og Nessie beregner ikke takster. Nessie læser færdige visningsværdier og viser dem.
Hemmeligheder
Der kræves en konfigureret vault for overhovedet at gemme en hemmelighed. Der er med vilje ingen databasefallback og ingen klartekststi: uden en vault giver gemning, rotation og tilbagekaldelse af en hemmelighed en fejl i stedet for at glide over i noget mindre sikkert. Nessies egne optegnelser om en hemmelighed indeholder ingen værdi, ingen chiffertekst, ingen nøgle og intet vault-token — kun en uigennemsigtig reference og dens metadata — og vault-stier bygges kun af strukturelle identifikatorer, aldrig af navnet på en organisation, et team, et projekt eller en person.
Legitimationsoplysninger, som Nessie selv skal opbevare for at fungere som OAuth-klient — oplysninger til connectorer og postkasser, webhook-hemmeligheder, materiale til fornyelse af sessioner og executor-payloads — er forseglet i formålsbundne AES-256-GCM-konvolutter under en versioneret nøglering, som er en separat rod fra sessionens signeringshemmelighed, med en dokumenteret rotationsprocedure.
Der er også en regel om modeller: en hemmelighed må gerne være kendt og godkendt til brug, men hemmeligt materiale må ikke komme ind i modelkontekst, prompts, værktøjsargumenter, værktøjsresultater, hukommelse, embeddings, søgning, logs eller beskeder. En agent kan få lov til at bruge en hemmelighed. Den kan aldrig få lov til at afsløre en.
Om de underliggende diske er krypterede, er en egenskab ved den maskine, en installation kører på. Repositoriet fastslår ikke kryptering på volumenniveau for database- og objektlagervolumenerne, så denne side påstår det ikke.
Isolation mellem tenants
Nessie er multi-tenant fra grunden: én database, hvor hver række tilhører præcis én organisation, og hver underordnet tabel har en organization_id. Isolationen håndhæves to steder — den scope-klausul, som hver forespørgsel bærer, og rigtige fremmednøgler på den kolonne, som blev tilføjet i toogfyrre constraints, efter at en intern gennemgang fandt kolonnen til stede, men uden constraint, på snesevis af tabeller.
En conformance-suite holder den invariant på plads ved HTTP-grænsen. Den opretter en maksimalt privilegeret angriber — en fuld ejer af sin egen organisation — og kontrollerer, at hver kanonisk læsning af en anden organisations ressourcer besvares med 403, 404 eller tomt, og at hver kanonisk ændring afvises, uden at den anden organisations række røres. Den dækker kanaler, godkendelser, revisionsloggen, triggere, agenter og deres bindinger, kørsler, projekter, opgaver, tråde, forbindelser, workflow-installationer, MCP-instanser, vidensbasen og alarmer.
For at være præcis om mekanismen: dette er håndhævelse på applikationsniveau plus fremmednøgler, ikke PostgreSQL row-level security. Der er ingen RLS-politik og intet sikkerhedsnet på databasesiden, og conformance-suiten kører mod et tro, hukommelsesbaseret lager og ikke en live database, så den beviser de scope-klausuler, koden skriver, og ikke den SQL, en server udfører. Det står i suitens egen dokumentation i repositoriet, og det står også på denne side.
Revisionssporet
Enhver handling af betydning registreres: hvem der handlede og som hvad — en person, en agent, en tjeneste — hvad vedkommende gjorde, med hvilken ressource, i hvilken organisation, hvilket projekt, team eller hvilken kanal, om det lykkedes eller blev afvist, hvorfor, samt forespørgslens id, adresse og user agent.
Loggen er med vilje kun-tilføjelse, og der er ingen måde at skrive til den udefra: POST /api/audit-log findes ikke, og det er bevidst. Indgangene er kædet sammen — hver indeholder et SHA-256-digest af sine egne kanoniske felter plus digestet af den foregående indgang for den organisation — så en ændret eller fjernet række bryder kæden og kan opdages. En organisationsejer eller administrator kan gennemgå den kæde efter behov og får at vide, hvor den først blev brudt, hvis den blev det.
To ærlige forbehold. Kæden gør loggen manipulationsafslørende, ikke immun over for manipulation: der er ingen tilbagekaldelse af skriveadgang på databaseniveau og intet write-once-lager bag den, så garantien er opdagelse og ikke forebyggelse. Og indgangene opbevares som standard uden tidsgrænse — konfigurerbar opbevaringstid med eksport før sletning er designet, men ikke bygget. Indgange må desuden ikke indeholde hemmeligheder eller komplette request bodies, og et fast sæt følsomme metadatafelter redigeres bort på vej ind.
Omkostningsregnskabet
Hvert modelkald registreres på organisationen og på den bruger, det team, det projekt, den kanal, den agent og den kørsel, det kom fra, med de tokens, det brugte, og både udbyderens rapporterede pris og Nessies eget skøn ved siden af hinanden. En måling, som en udbyder ikke rapporterer, gemmes som null i stedet for at blive gættet. Rapporterne kan læses af en organisationsejer eller administrator.
Dette regnskab er operationel telemetri — hvad en organisation har brugt, og på vegne af hvem. Det er ikke en faktura og ikke en faktureringsautoritet.
Tredjeparter, når du bruger det hostede produkt
En hostet installation taler med et lille, fast sæt tjenester. Modeltrafik og websøgning går ikke direkte til udbyderne: begge forlader systemet gennem én gateway, som UnlikeOtherAI driver, og det er dér, de underliggende model- og søgeudbydere sidder. Login og fakturering går til UnlikeOtherAIs authenticator. Hemmelighedsvaulten er selvhostet ved siden af applikationen. Videoopkaldslinks, som serveren opretter, bruger som standard den offentlige Jitsi-tjeneste.
Næsten alt andet er slået fra, indtil en driftsansvarlig konfigurerer det, og siger det i stedet for at fejle i det stille: forbundne Google-, Microsoft- og Slack-konti; agent-e-mail via Amazon SES, som en installation kører i sin egen konto uden mellemled; mobil- og browser-push; connectorer til research og tavlekilder; cloudbrowsere. To detaljer er værd at nævne, fordi de ændrer, hvor data havner:
- Forbundne postkasser bliver hos din udbyder. Mail læses direkte hos din udbyder, over IMAP og SMTP eller udbyderens eget login; Nessie gemmer den forseglede legitimationsoplysning og intet andet om kontoen. En postkasse, du forbinder til kundeindbakken, er undtagelsen: du beder om, at dens samtaler bliver gemt hos hver kunde, så de kopieres ind.
- Taleopkald i appen går ikke gennem Nessie. API'et formidler en legitimationsoplysning, og klienten åbner selv lydforbindelsen. Diktering og telefonopkald er anderledes: deres lyd går gennem Nessie til de tale- og modeludbydere, der behandler den.
En detalje ved inferens følger samme princip: signerede headers med kalderens identitet sendes kun til den konfigurerede chatvært, så hvis du peger embeddings mod et andet endpoint, får det endpoint aldrig en delegationspåstand om den person, hvis tekst bliver embeddet.
Det hostede produkt bruger flere inferensudbydere og vælger mellem dem ud fra pris og kvalitet. En organisation vil kunne vælge i Admin, hvilke udbydere dens agenter må bruge: kun vestlige, kun europæiske, kun kinesiske eller ingen præference — den mest effektive udbyder til hvert job. En selvhostet instans vælger selv.
Hvis du kører det selv, ændrer det alt det ovenstående
Hver tredjepart ovenfor er et konfigurationsvalg på en selvhostet instans. Inferens kan pege mod ethvert OpenAI-kompatibelt endpoint, også et på din egen hardware. Connectorerne er slået fra, medmindre du slår dem til. UnlikeOtherAI-login er den understøttede vej, og en installation helt uden identitetsudbyder kører som én enkelt ubundet organisation med en bootstrap-ejer.
Det er hele meningen med ordningen: softwaren er den samme, og beslutningerne om, hvor den kører, og hvad den må nå, tilhører den, der driver den. Hvordan, står på installationssiden.