Architektur & Sicherheit
Wie Customermates gebaut ist, wie Daten isoliert sind, und wie externer KI-Zugriff kontrolliert wird.
Customermates erzwingt ein Single-Tenant-pro-Company-Datenmodell auf jeder Ebene. Jeder Datensatz ist auf eine Company begrenzt, API-Keys tragen die Identität des Owner-Users, und Agents sehen nur das, was dieser User sehen darf.
Stack
- Next.js 16 (App Router, Turbopack): Web-App und API.
- PostgreSQL: primärer Datastore. JSONB für Custom-Column-Werte und Webhook-Payloads.
- Prisma: ORM und Migrationen.
- better-auth: Sessions, Social-Login, API-Keys, MCP-OAuth.
- mcp-handler: Model-Context-Protocol-Endpoint.
- TypeScript durchgängig, Zod-validiert an jeder Grenze.
Tenancy
Jeder Datensatz gehört zu einer Company. Die Company-ID wird an drei Stellen erzwungen:
- App-Layer: jeder Interactor löst die Company des aktuellen Users auf und filtert danach.
- Prisma-Layer: Queries enthalten
companyIdin jedemwhere. - Decorator-Layer:
@TenantInteractorsorgt dafür, dass Interactors, die den Scope vergessen, zur Laufzeit werfen.
Cross-Tenant-Reads sind über die öffentliche Oberfläche nicht möglich. Es gibt kein Admin-Panel, das den Scope umgeht.
Authentifizierung
Drei Wege:
- Session-Cookie (UI): signiert, http-only,
Secureunter HTTPS. - API-Key: 64-Zeichen-Base62-Token (a-z, A-Z, 0-9), ausgestellt vom better-auth-apiKey-Plugin, at-rest gehasht, an einen User gebunden. Wird im Header
x-api-keygesendet. - OAuth 2.1 (MCP): Remote-MCP-Clients können sich über better-auth autorisieren und statt eines API-Keys ein Bearer-Token senden.
Alle Methoden lösen auf denselben User- und Company-Kontext auf.
Autorisierung
Pro User und rollenbasiert. Rollen tragen Permissions auf Resources (Contacts, Organizations, Deals, Services, Tasks) und Actions (Read, Create, Update, Delete). Jeder Interactor ruft userService.hasPermissionOrThrow(resource, action), bevor er handelt.
API-Keys erben die Rechte ihres Owner-Users. Es gibt kein Scoping pro Key.
Externer KI-Zugriff
MCP-Requests nutzen denselben Authentifizierungs- und Autorisierungspfad. Wenn ein Agent über MCP handelt:
- Er ruft
/api/v1/mcpmit einem API-Key oder einem OAuth-Bearer-Token. - Der Server löst User und Company aus dem Credential auf.
- Jeder Tool-Call läuft in einem Tenant-Scope.
- Validierungsfehler liefern strukturierte Meldungen mit Remediation-Hints und leaken keine internen Schema-Details.
Die MCP-Oberfläche fügt Input-Guardrails hinzu, die Tool-Calls absichern:
nullauf einem Relation-Array wird abgelehnt, bevor es die Datenbank erreicht.- Update-Tools für den falschen Record-Typ werden mit einem Verweis auf das richtige Tool abgelehnt.
- Destruktive Tools verlangen eine explizite Liste von Record-IDs. Es gibt keinen Delete-by-Filter-Shortcut.
Den vollständigen Tool-Katalog finden Sie unter MCP.
Daten at-rest
- Die Postgres-Verschlüsselung hängt vom Provider ab. In der Managed-Cloud liegen die Daten in einer EU-Region mit Disk-Level-Encryption at-rest.
- Secrets in
.envwerden nie geloggt. Der Logger redaktiert alles, was wie ein Key, Token oder Passwort aussieht. - Webhook-Secrets liegen in Postgres, weil sie abrufbar sein müssen, um ausgehende Requests zu signieren. Wenn Sie sie woanders halten wollen, self-hosten Sie mit Ihrem eigenen Secret-Manager.
Daten in-transit
- HTTPS überall in der Managed-Cloud.
- Bei Self-Host stellen Sie das TLS selbst bereit. Das Caddy-Beispiel finden Sie unter Self-Hosting.
- Webhook-Deliveries gehen nur an HTTPS-URLs. HTTP wird auf Schema-Ebene abgelehnt.
Audit-Logging
Jeder Write wird mit User, Action, Entity sowie Vorher- und Nachher-Werten geloggt. Er ist aus der UI abfragbar und als JSON exportierbar. Audit-Logging ist in jedem Cloud-Plan enthalten. Die selbstgehostete Community-Edition enthält kein Audit-Logging.
Vulnerabilities melden
Bitte melden Sie verantwortungsvoll an security@customermates.com. Der PGP-Key liegt im Repository. Wir bestätigen den Eingang innerhalb von 24 Stunden.
Weiter
- Self-Hosting: Customermates selbst betreiben.
- API-Keys: Regeln zur Key-Hygiene.
- MCP: wie die KI-Oberfläche geformt ist.