nessie

In der EU entwickelt und dort, wo Ihre Daten liegen

Wo Nessie entwickelt wird, wo Ihre Daten liegen und was Sie kontrollieren, wenn Sie selbst hosten.

Wer es baut und nach welchem Recht

Nessie wird von UnlikeOtherAI s.r.o. entwickelt, einem in der Tschechischen Republik eingetragenen Unternehmen, das nach tschechischem Recht tätig ist.

Diese Seite beschreibt, wie die Software aufgebaut ist und wo sie läuft. Sie ist keine Compliance-Erklärung: Nessie besitzt keine Sicherheitszertifizierung, und nichts hier sollte als eine solche verstanden werden. Welche personenbezogenen Daten verarbeitet werden und auf welcher Grundlage, regelt die Datenschutzerklärung, eine eigene Seite.

Wo das gehostete Produkt läuft

Nessie Cloud läuft bei europäischen Hosting-Anbietern – Scaleway, Hetzner und weiteren. Wir wählen von jedem Anbieter den besten Dienst, sodass verschiedene Teile des Produkts bei verschiedenen Anbietern laufen können, alle in Europa.

Genauere Angaben – ein bestimmter Standort, eine Stadt oder ein Rechenzentrum – machen wir hier bewusst nicht, weil sie unbemerkt veralten würden.

Beim Self-Hosting entscheiden Sie

Wo eine selbst gehostete Instanz läuft, ist eine Einstellung der Bereitstellung, keine Einstellung des Produkts. Der Weg für einen einzelnen Rechner ist ein Docker-Compose-Stack, den Sie auf einem Rechner Ihrer Wahl einrichten. In der Terraform-Konfiguration für eine verwaltete Cloud ist die Region ein Eingabewert ohne jeden Standardwert: Nichts davon lässt sich erraten, also gibt es dort keinen Standard, und die Datenbank, der Object-Storage-Bucket und die Dienste folgen alle der Region, die Sie angeben.

Für dieselbe Frage sind zwei Aufbaudetails wichtig. Die Warteschlange und der Echtzeit-Transport sind beide PostgreSQL – es gibt weder Redis noch einen Message-Broker im Pfad, also kein drittes System, das untergebracht werden müsste. Und der Object Storage ist S3-kompatibel statt an einen Anbieter gebunden; die Referenzbereitstellung betreibt MinIO in einem Container in einem privaten Netzwerk ohne eigenen Zugang von außen. Die Teile, die irgendwo liegen müssen, sind die Datenbank, der Object Store und die beiden Node-Dienste, und sie liegen alle dort, wo Sie sie hinstellen. Wie Sie das einrichten, steht auf der Installationsseite.

Was Nessie speichert – und was bewusst nicht

Identitäten werden nicht kopiert

Bei der Anmeldung über UnlikeOtherAI verwaltet und speichert der Identitätsanbieter die Identität von Personen – Authentifizierungsfaktoren, Profile, Mitgliedschaft in Organisationen und Teams sowie Einladungen. Nessie ist eine Relying Party, kein zweites Identitätssystem. Das ist ebenso eine Datenentscheidung wie eine architektonische: Eine Identität, die Nessie nie speichert, kann Nessie weder preisgeben noch verlieren noch vergessen zu löschen.

Die Tabelle users hält tatsächlich nur Folgendes: die stabile Benutzerkennung des Anbieters – den Schlüssel, über den alles andere aufgelöst wird –, die E-Mail-Adresse, eine nicht maßgebliche Spiegelung von Anzeigename und Avatar sowie produktlokale Felder (Einstellungen, Pronomen, eine Token-Version zum Widerrufen von Sitzungen). Die Spiegelung gibt es nur, damit Name und Bild ohne eine Anfrage pro Zeile angezeigt werden können; sie wird bei der Anmeldung, beim Teamwechsel und bei der Sitzungserneuerung aus den verifizierten Claims des Anbieters neu abgeglichen. Nichts erzeugt einen Wert aus dem Nichts: Eine Person, die der Anbieter nicht benannt hat, erscheint mit ihrer E-Mail-Adresse, bis er es tut. Einen Passwort-Hash gibt es nur für den Bootstrap-Inhaber einer Installation ganz ohne Identitätsanbieter.

Dasselbe gilt für die Struktur. Eine Organisation des Anbieters ist eine Nessie-Organisation, verbunden über die Organisations-ID des Anbieters; ein Team ohne Verknüpfung zum Anbieter antwortet mit 404 TEAM_NOT_LINKED, statt auf eine lokale Vermutung auszuweichen, und ein Live-Abruf der Mitgliederliste geht an den Identitätsanbieter und speichert nichts.

Zwei Spiegelungen sind noch nicht abgeschafft, und es wäre unehrlich, etwas anderes anzudeuten. Die Namen von Organisationen und Teams werden weiterhin lokal neben den Bindungs-IDs gespeichert, und lokale Mitgliedschaftszeilen autorisieren gewöhnliche Anfragen zwischen den Synchronisierungen weiterhin. Beides zu entfernen ist offene, im Repository verfolgte Arbeit und nichts, was schon erledigt wäre.

Nichts Kommerzielles

Der zentrale Abrechnungsdienst verwaltet die Zahlungen. Nessie speichert keine Kunden, Abonnements, Rechnungen, Preise, Guthaben, Aufladeregeln, Zahlungseinwilligungen, Kontoauszüge oder Kündigungsstände eines Zahlungsanbieters und berechnet keine Tarife. Es liest anzeigefertige Werte und zeigt sie an.

Geheimnisse

Um überhaupt ein Geheimnis zu speichern, ist ein konfigurierter Tresor (Vault) erforderlich. Es gibt bewusst keinen Datenbank-Ersatz und keinen Klartextpfad: Ohne Tresor liefern das Speichern, Rotieren und Widerrufen eines Geheimnisses einen Fehler, statt auf etwas weniger Sicheres auszuweichen. Nessies eigene Datensätze zu einem Geheimnis enthalten keinen Wert, keinen Chiffretext, keinen Schlüssel und kein Tresor-Token – nur eine undurchsichtige Referenz und ihre Metadaten –, und Tresorpfade werden ausschließlich aus strukturellen Kennungen gebildet, nie aus dem Namen einer Organisation, eines Teams, eines Projekts oder einer Person.

Zugangsdaten, die Nessie selbst halten muss, um als OAuth-Client zu handeln – Zugangsdaten für Konnektoren und Postfächer, Webhook-Geheimnisse, Material zur Sitzungserneuerung, Executor-Nutzdaten –, werden in zweckgebundenen AES-256-GCM-Umschlägen versiegelt, unter einem versionierten Schlüsselbund, der eine vom Signaturgeheimnis der Sitzungen getrennte Wurzel ist, mit einem dokumentierten Rotationsverfahren.

Dazu gibt es eine Regel für Modelle: Ein Geheimnis darf als vorhanden bekannt sein und zur Verwendung freigegeben werden, aber Geheimnismaterial darf nicht in Modellkontext, Prompts, Tool-Argumente, Tool-Ergebnisse, Gedächtnis, Embeddings, Suche, Logs oder Nachrichten gelangen. Ein Agent kann die Berechtigung erhalten, ein Geheimnis zu verwenden. Die Berechtigung, eines offenzulegen, kann er nie erhalten.

Ob die zugrunde liegenden Datenträger verschlüsselt sind, ist eine Eigenschaft des Rechners, auf dem eine Bereitstellung läuft. Das Repository legt keine Verschlüsselung auf Datenträgerebene für die Datenbank- und Object-Storage-Volumes fest, deshalb behauptet diese Seite sie nicht.

Mandantentrennung

Nessie ist von Grund auf mandantenfähig: eine Datenbank, in der jede Zeile genau einer Organisation gehört und jede untergeordnete Tabelle eine organization_id trägt. Die Trennung wird an zwei Stellen durchgesetzt – in der Bereichsklausel, die jede Abfrage enthält, und in echten Fremdschlüsseln auf dieser Spalte, die in zweiundvierzig Constraints ergänzt wurden, nachdem ein internes Audit festgestellt hatte, dass die Spalte in Dutzenden Tabellen zwar vorhanden, aber nicht abgesichert war.

Eine Konformitätstestsuite hält diese Invariante an der HTTP-Grenze fest. Sie legt einen maximal privilegierten Angreifer an – den vollen Inhaber seiner eigenen Organisation – und prüft, dass jeder kanonische Lesezugriff auf Ressourcen einer anderen Organisation mit 403, 404 oder einem leeren Ergebnis beantwortet wird und jede kanonische Änderung abgelehnt wird, ohne dass der Datensatz der anderen Organisation angetastet wird. Sie deckt Kanäle, Freigaben, das Audit-Protokoll, Trigger, Agenten und ihre Bindungen, Läufe, Projekte, Aufgaben, Threads, Verbindungen, Workflow-Installationen, MCP-Instanzen, die Wissensbasis und Benachrichtigungen ab.

Zum Mechanismus ganz genau: Es handelt sich um Durchsetzung auf Anwendungsebene plus Fremdschlüssel, nicht um Row-Level-Security von PostgreSQL. Es gibt keine RLS-Richtlinie und keine Absicherung auf Datenbankseite, und die Konformitätstestsuite läuft gegen einen originalgetreuen In-Memory-Speicher statt gegen eine echte Datenbank. Sie belegt also die Bereichsklauseln, die der Code schreibt, nicht das SQL, das ein Server ausführt. Das Repository sagt das in der Dokumentation der Testsuite selbst, und diese Seite sagt es ebenso.

Der Audit-Trail

Jede folgenreiche Aktion wird festgehalten: wer gehandelt hat und als was – Person, Agent, Dienst –, was getan wurde, an welcher Ressource, in welcher Organisation, welchem Projekt, Team oder Kanal, ob es gelang oder verweigert wurde, warum, und mit welcher Anfrage-ID, Adresse und welchem User-Agent die Anfrage ankam.

Das Log ist von Grund auf nur anfügbar, und es gibt keine Möglichkeit, von außen hineinzuschreiben: POST /api/audit-log existiert nicht, und das ist Absicht. Die Einträge sind verkettet – jeder trägt einen SHA-256-Digest seiner eigenen kanonischen Felder plus den Digest des vorherigen Eintrags dieser Organisation –, sodass eine geänderte oder entfernte Zeile die Kette bricht und erkennbar ist. Ein Inhaber oder Admin der Organisation kann die Kette jederzeit durchlaufen lassen und erfährt, wo sie zuerst gebrochen ist, falls sie es ist.

Zwei ehrliche Einschränkungen. Die Kette macht das Log manipulationssichtbar, nicht manipulationssicher: Dahinter stehen weder ein Entzug der Schreibrechte auf Datenbankebene noch einmal beschreibbarer Speicher, die Garantie ist also Erkennung, nicht Verhinderung. Und Einträge werden standardmäßig unbegrenzt aufbewahrt – konfigurierbare Aufbewahrung mit Export vor dem Löschen ist entworfen, nicht gebaut. Einträge dürfen außerdem keine Geheimnisse oder vollständigen Anfragekörper enthalten, und eine feste Menge sensibler Metadatenfeldnamen wird beim Eintragen geschwärzt.

Das Kostenhauptbuch

Jeder Modellaufruf wird der Organisation zugeordnet, ebenso dem Benutzer, dem Team, dem Projekt, dem Kanal, dem Agenten und dem Lauf, von denen er stammt – mit den verbrauchten Tokens, wobei die vom Anbieter gemeldeten Kosten und Nessies eigene Schätzung nebeneinander gespeichert werden. Eine Kennzahl, die ein Anbieter nicht meldet, wird als null gespeichert, nicht geraten. Berichte kann ein Inhaber oder Admin der Organisation einsehen.

Dieses Kostenhauptbuch ist Betriebstelemetrie – was eine Organisation ausgegeben hat und in wessen Auftrag. Es ist keine Rechnung und keine Abrechnungsinstanz.

Drittanbieter, wenn Sie das gehostete Produkt nutzen

Eine gehostete Bereitstellung spricht mit einer kleinen, festen Menge von Diensten. Modellverkehr und Websuche gehen nicht direkt an Anbieter: Beides verlässt das System über ein Gateway, das UnlikeOtherAI betreibt und hinter dem die vorgelagerten Modell- und Suchanbieter stehen. Anmeldung und Abrechnung gehen an den Authentifizierungsdienst von UnlikeOtherAI. Der Geheimnis-Tresor wird selbst neben der Anwendung betrieben. Vom Server erzeugte Videoanruf-Links verwenden standardmäßig den öffentlichen Jitsi-Dienst.

Fast alles andere ist ausgeschaltet, bis ein Betreiber es konfiguriert, und sagt das, statt stillschweigend zu scheitern: verbundene Google-, Microsoft- und Slack-Konten; Agenten-E-Mail über Amazon SES, das eine Bereitstellung in ihrem eigenen Konto ohne Zwischenstelle betreibt; Push auf Mobilgeräten und im Browser; Konnektoren für Recherche und Board-Quellen; Cloud-Browser. Zwei Einzelheiten sind erwähnenswert, weil sie ändern, wohin Daten gehen:

  • Verbundene Postfächer bleiben bei Ihrem Anbieter. E-Mails werden live bei Ihrem Anbieter gelesen, über IMAP und SMTP oder die eigene Anmeldung des Anbieters; Nessie speichert die versiegelten Zugangsdaten und sonst nichts über das Konto. Ein Postfach, das Sie mit dem Clients-Posteingang verbinden, ist die Ausnahme: Sie verlangen, dass seine Gespräche beim jeweiligen Kunden aufbewahrt werden, deshalb werden sie kopiert.
  • Sprachanrufe in der App laufen nicht über Nessie. Die API vermittelt eine Zugangsberechtigung, und der Client baut die Audioverbindung selbst auf. Diktat und Telefonanrufe sind anders: Ihr Audio läuft über Nessie zu den Sprach- und Modellanbietern, die es verarbeiten.

Ein Detail bei der Inferenz folgt demselben Prinzip: Signierte Header mit der Identität des Aufrufers werden nur an den konfigurierten Chat-Host gesendet, sodass ein auf einen anderen Endpunkt gelegtes Embedding diesem Endpunkt nie eine Delegationsbestätigung über die Person liefert, deren Text eingebettet wird.

Das gehostete Produkt nutzt mehrere Inferenzanbieter und wählt je nach Kosten und Qualität zwischen ihnen. Eine Organisation wird in der Admin-Oberfläche festlegen können, welche Anbieter ihre Agenten nutzen dürfen: nur westliche, nur europäische, nur chinesische oder ohne Präferenz – der effizienteste Anbieter für jede Aufgabe. Eine selbst gehostete Instanz wählt selbst.

Wenn Sie es selbst betreiben, ändert sich all das

Jeder Drittanbieter oben ist bei einer selbst gehosteten Instanz eine Konfigurationsentscheidung. Die Inferenz kann auf jeden OpenAI-kompatiblen Endpunkt gerichtet werden, auch auf einen auf Ihrer eigenen Hardware. Die Konnektoren sind aus, solange Sie sie nicht einschalten. Die Anmeldung über UnlikeOtherAI ist der unterstützte Weg, und eine Bereitstellung ganz ohne Identitätsanbieter läuft als einzelne ungebundene Organisation mit einem Bootstrap-Inhaber.

Darum geht es bei dieser Anordnung: Die Software ist dieselbe, und die Entscheidungen darüber, wo sie läuft und was sie erreichen darf, gehören dem, der sie betreibt. Wie das geht, steht auf der Installationsseite.