iToverDose/Software· 26 JUNI 2026 · 04:00

Teamwissen sicher verwalten: MCP-Server mit nutzerbasierter Authentifizierung

Die Nutzung eines einzigen API-Schlüssels für ein Team-Knowledge-Base-Tool führt zu Sicherheitslücken. Erfahren Sie, wie neue Authentifizierungsmechanismen individuelle Zugriffe ermöglichen und Audits verbessern.

DEV Community4 min0 Kommentare

Die Verwaltung von Teamwissen in einer zentralen Wissensdatenbank stellt viele Entwicklerteams vor Herausforderungen – besonders wenn es um Sicherheit und individuelle Zugriffskontrolle geht. Das Plugin intent-brain, kürzlich in Version 0.4.0 aktualisiert, setzt nun auf nutzerbasierte Tokens, um diese Probleme zu lösen. Doch warum ist die API der eigentliche Sicherheitsanker und nicht die Client-Oberfläche?

Das Tool intent-brain fungiert als Wissensdatenbank für Teams und nutzt ein Fastify-REST-API, das auf einem kontrollierten Speicherkorpus aufsetzt. Bisher authentifizierten sich alle Teammitglieder über einen einzigen API-Schlüssel (TEAMKB_API_KEY). Doch diese Lösung erwies sich als problematisch: Zum einen ließ sich nicht nachvollziehen, welcher Nutzer eine Anfrage gestellt hatte, da alle Anfragen identisch erschienen. Zum anderen führte die Sperrung eines Schlüssels zu einer kompletten Neugestaltung des Zugriffs für das gesamte Team – ein administrativer Albtraum.

Diese strukturellen Schwächen erforderten eine grundlegende Überarbeitung der Authentifizierung. Das Team entschied sich für ein dreistufiges Sicherheitskonzept: individuelle Nutzer-Tokens zur Identitätsprüfung, ein serverseitiges Schreibrecht zur Autorisierung und ein separates Lesezugriffsprotokoll für Audits. Der zentrale Gedanke dahinter: Die API selbst bildet die eigentliche Sicherheitsgrenze, nicht die Client-Software.

Individuelle Tokens ersetzen den gemeinsamen Schlüssel

Die neue Authentifizierung wird im Modul apps/api/src/auth/token-registry.ts verwaltet. Jedes Token verweist auf einen Datensatz mit den Feldern { actor, role }, wobei role entweder admin oder member sein kann. Diese Struktur löst gleich zwei Probleme der alten Lösung: Jede Anfrage enthält nun den eindeutigen Nutzer (actor), und die Sperrung eines Tokens betrifft nur den jeweiligen Nutzer – nicht das gesamte Team.

Die Token-Generierung folgt einer klaren Prioritätenliste:

  • Explizit definierte Tokens in der Datenbank
  • Eine Umgebungsvariable TEAMKB_TOKENS im JSON-Format
  • Eine Datei TEAMKB_TOKENS_FILE (standardmäßig ~/.teamkb/tokens.json)
  • Der veraltete gemeinsame API-Schlüssel, der nun als Admin-Token mit dem Nutzer "shared" fungiert

Jeder Eintrag besteht aus einem Bearer-Token, das zur Laufzeit in eine Nutzeridentität aufgelöst wird. Fehlerhafte Einträge werden übersprungen, um einen Systemabsturz zu vermeiden. Tokens ohne Rollenangabe erhalten standardmäßig den Status member – das Prinzip der geringsten Rechte wird hier konsequent umgesetzt. Im Entwicklungsmodus ist das Registry leer und alle Anfragen laufen unter dem Nutzer "dev"; in der Produktion führt ein leeres Registry zu einem abgeschlossenen System (fail closed).

Das Herzstück der Implementierung ist die Klasse InMemoryTokenRegistry, die bewusst auf bestimmte Funktionen verzichtet:

export class InMemoryTokenRegistry implements TokenRegistry {
  private readonly records: ReadonlyArray<TokenRecord>;

  constructor(records: readonly TokenRecord[]) {
    this.records = records;
  }

  isEmpty(): boolean {
    return this.records.length === 0;
  }

  resolve(token: string): TokenIdentity | undefined {
    let found: TokenIdentity | undefined;
    for (const rec of this.records) {
      // Kein Early-Return bei Treffer – Durchlauf aller Tokens
      if (timingSafeStrEq(rec.token, token)) {
        found = { actor: rec.actor, role: rec.role };
      }
    }
    return found;
  }
}

Zwei Details verdienen besondere Aufmerksamkeit: Die Funktion timingSafeStrEq führt einen konstantzeitigen Vergleich durch, um Timing-Angriffe zu verhindern – ein Nutzer darf nicht anhand der Antwortzeit Rückschlüsse auf Token-Inhalte ziehen. Zudem durchläuft die Methode resolve() alle Tokens, bevor sie zurückgibt. Ein vorzeitiger Abbruch bei einem Treffer würde ein Timing-Leck erzeugen: Tokens, die früh im Registry stehen, würden schneller aufgelöst als solche am Ende. Durch den vollständigen Durchlauf bleibt die Antwortzeit unabhängig vom Treffer.

Die Authentifizierungs-Middleware ruft resolve() auf und schreibt die Nutzeridentität (request.actor) sowie die Rolle (request.role) in die Anfrage. Alle nachgelagerten Systeme – das Schreibrecht-Gate, das Zugriffsprotokoll – nutzen diese Felder als vertrauenswürdige Quelle. Die Identität wird somit einmalig am Systemrand etabliert und von der gesamten Architektur übernommen.

Serverseitiges Schreibrecht-Gate schützt sensible Aktionen

Im Modul apps/api/src/middleware/write-gate.ts wird ein zentrales Schreibrecht-Gate implementiert. Mitglieder dürfen lesen und Vorschläge einreichen, doch kritische Aktionen wie das Veröffentlichen von Inhalten, das Bearbeiten von Richtlinien oder Massenimports erfordern Admin-Rechte. Diese Kontrolle erfolgt über einen Fastify-Hook (onRequest), der nach der Authentifizierung und vor der Verarbeitung der Anfrage ausgeführt wird:

const ADMIN_WRITE_PREFIXES = [
  '/api/memories',
  '/api/policies',
  '/api/import'
];

const MUTATION_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);

export function registerWriteGate(app: FastifyInstance): void {
  app.addHook('onRequest', async (request, reply) => {
    if (!MUTATION_METHODS.has(request.method)) return;

    const path = request.url.split('?')[0] ?? request.url;
    const isAdminWrite = ADMIN_WRITE_PREFIXS.some(
      (prefix) => path === prefix || path.startsWith(`${prefix}/`)
    );

    if (!isAdminWrite) return;

    if (request.role !== 'admin') {
      reply.status(403);
      throw new Error(
        'Diese Aktion erfordert ein Admin-Token. Mitglieder dürfen lesen und Vorschläge einreichen; Veröffentlichungen, Richtlinienänderungen und Importe sind Admin-Rechte vorbehalten.'
      );
    }
  });
}

Das Gate prüft sowohl die HTTP-Methode (nur POST, PUT, PATCH oder DELETE kommen infrage) als auch den Pfad der Anfrage. Eine Leseanfrage (GET) oder eine schreibende Anfrage an eine nicht-administrative Route wird ohne weitere Prüfung durchgelassen. Doch sobald eine mutierende Methode auf einen der administrativen Pfade (/api/memories, /api/policies oder /api/import) abzielt, muss die Rolle admin nachgewiesen werden. Diese Logik wird in einem Hook implementiert, der jeder Anfrage unterliegt – unabhängig davon, über welche Client-Schnittstelle sie gestellt wurde.

MCP-Client als UX-Tool, nicht als Sicherheitsanker

Der apps/mcp-server/src/server.ts implementiert den MCP-Server, der die zuvor beschriebenen Sicherheitsmechanismen widerspiegelt. Lesezugriffs-Tools wie teamkb_search, teamkb_status oder teamkb_neighbors sind immer verfügbar, unabhängig vom Nutzerstatus. Schreibzugriffs-Tools werden hingegen nur für Admin-Installationen registriert. Die Entscheidung basiert auf demselben canWrite-Flag, das bereits in der Server-Konfiguration genutzt wird:

const canWrite = options.canWrite ?? config.role === 'admin';

// Lese-Tools – immer registriert (für Mitglieder und Admins)
server.tool('teamkb_search', /* ...zitierte Abfrage...

Wichtig ist hier der Grundsatz: Der MCP-Client dient als benutzerfreundliche Schnittstelle, nicht als Sicherheitsmechanismus. Die eigentliche Kontrolle findet auf Serverseite statt – in der API und den implementierten Hooks. Selbst wenn ein Nutzer versuchen würde, über den MCP-Client unerlaubte Aktionen auszuführen, würde das serverseitige Schreibrecht-Gate diese abfangen.

Sicherheit in kollaborativen Entwicklungsumgebungen erfordert mehr als nur ein Passwort oder einen gemeinsamen Schlüssel. Die neue Authentifizierungsstrategie von intent-brain zeigt, wie individuelle Tokens, serverseitige Autorisierung und detaillierte Audit-Protokolle zusammenwirken, um ein robustes und skalierbares System zu schaffen. Während der MCP-Client die Interaktion vereinfacht, bleibt die API der entscheidende Sicherheitsanker – ein Prinzip, das jedes Entwicklungsteam bei der Planung verteilter Wissenssysteme berücksichtigen sollte.

KI-Zusammenfassung

Ekip bilgi tabanlarınızı güvenli hale getirmek için kullanıcı özel tokenleri, sunucu tarafı yazma koruması ve ayrıntılı erişim kayıtları kullanın. API katmanı gerçek güvenlik sınırıdır.

Kommentare

00
KOMMENTAR SCHREIBEN
ID #AYDNRY

0 / 1200 ZEICHEN

Menschen-Check

5 + 7 = ?

Erscheint nach redaktioneller Prüfung

Moderation · Spam-Schutz aktiv

Noch keine Kommentare. Sei der erste.