MCP Fusion/Security and governance/Authentifizierung

Authentifizierung

Frag die KI über Vinkius

Drei Authentifizierungspakete für Konnektoren: JWT-Prüfung mit JWKS, zeitkonstante API-Schlüssel und der OAuth-2.0-Geräteautorisierungsfluss als vom Agenten steuerbare Tools.

Ein Konnektor, der auf das Konto einer Person zugreift, muss wissen, wer die Anfrage stellt. MCP Fusion liefert drei Authentifizierungspakete, jeweils mit Middleware und optionalem Auth-Tool, damit der Agent blockiert, herausgefordert und anschließend freigegeben werden kann, ohne dass Ihr Handler den Unterschied kennt.

Woher die Identität kommt

Die Authentifizierung liest die Identität aus ctx, und ctx wird pro Request durch contextFactory erstellt. Die kanonische Verdrahtung:

typescript
registry.attachToServer(server, {
  contextFactory: async (extra) => ({
    token: extra.session?.authToken ?? '',
    headers: extra.headers ?? {},
  }),
});

Alles Folgende liest diesen Kontext.

JWT

bash
npm install @mcpfusion/jwt
typescript
import { requireJwt } from '@mcpfusion/jwt';

f.query('billing.list_invoices')
  .use(requireJwt({
    jwksUri: 'https://auth.example.com/.well-known/jwks.json',
    issuer: 'https://auth.example.com/',
    audience: 'my-connector',
    requiredClaims: ['sub', 'tenant_id'],
    onVerified: (ctx, payload) => {
      ctx.tenantId = payload.tenant_id;   // derived identity for the handler
    },
  }))
  .handle(async (input, ctx) => listInvoices(ctx.tenantId));

JwtVerifier akzeptiert secret (HS256), publicKey (PEM) oder jwksUri (entfernten Schlüsselsatz, pro Verifier gecacht). Mit installiertem jose funktionieren RS256, ES256 und JWKS. Ohne diese Bibliothek prüft ein nativer HS256-Pfad mit timingSafeEqual und lehnt jeden anderen Algorithmus ab. issuer, audience, clockTolerance (60 Sekunden) und requiredClaims werden bei jedem Token validiert. verifyDetailed() gibt { valid, payload, reason } zurück, wenn Sie den Grund statt null benötigen.

Die standardmäßige Tokenextraktion erfolgt in dieser Reihenfolge: ctx.token, dann ctx.jwt, dann ctx.headers.authorization (das Präfix Bearer wird entfernt). Fehler liefern einen selbstheilenden toolError mit dem Code JWT_INVALID und einer auth-Aktion zur Wiederherstellung.

Das JWT-Paket prüft Tokens, erneuert sie aber nicht. Der Quellcode unterstützt keine Refresh-Tokens. Ein Konnektor, der langfristigen Providerzugriff benötigt, sollte daher den OAuth-Fluss unten oder den Credential-Tresor verwenden.

Das optionale createJwtAuthTool() stellt verify und status als vom Agenten aufrufbare Aktionen bereit, wenn der Client selbst das Token besitzt.

API-Schlüssel

bash
npm install @mcpfusion/api-key
typescript
import { requireApiKey } from '@mcpfusion/api-key';

f.mutation('billing.refund')
  .use(requireApiKey({
    keys: [process.env.SERVICE_KEY!],
    onValidated: (ctx) => { ctx.service = 'billing-service'; },
  }))
  .handle(...);

Schlüssel können Klartext sein, beim Erstellen intern mit SHA-256 gehasht oder bereits gehasht sein, oder durch Ihre asynchrone validator-Funktion geprüft werden. Die Prüfungen erfolgen in dieser Reihenfolge: nicht leer, minLength (standardmäßig 16), optionales prefix, danach Validator oder Hash-Menge. Die Extraktion erfolgt über ctx.apiKey, ctx.headers['x-api-key'] und dann ctx.headers.authorization (die Präfixe ApiKey und Bearer werden entfernt).

Der Vergleich ist auf konstante Zeit ausgelegt: Der Manager vergleicht Hashes, ohne beim ersten abweichenden Byte abzubrechen. Behandeln Sie die Schlüssellänge nicht als Geheimnis.

OAuth-Gerätefluss für den Agenten

Wenn der Konnektor ein Konto benötigt, das der Agent noch nicht besitzt, muss der Ablauf aus einem Chat steuerbar sein: Der Server übergibt einen Code und eine URL, die Person bestätigt im Browser und der Agent fragt erneut. Das ist RFC 8628, und das Paket macht daraus Tools:

bash
npm install @mcpfusion/oauth
typescript
import { createAuthTool, requireAuth } from '@mcpfusion/oauth';

const auth = createAuthTool({
  clientId: process.env.OAUTH_CLIENT_ID!,
  authorizationEndpoint: 'https://auth.example.com/device/code',
  tokenEndpoint: 'https://auth.example.com/device/token',
  onAuthenticated: (token) => { /* cache or forward the token */ },
});

f.query('analytics.report')
  .use(requireAuth())          // blocks with AUTH_REQUIRED until a token exists
  .handle(...);

Das Tool stellt vier Aktionen bereit:

AktionVerhalten
loginfordert einen Gerätecode an und gibt Verifizierungs-URL und Code zurück
completetauscht den Code einmal ein; authorization_pending bedeutet "noch nicht, fragen Sie erneut"
statusmeldet, ob ein Token existiert und optional, zu welchem Benutzer es gehört
logoutlöscht das Token

Die Abfrageschleife beachtet RFC 8628: Die erste Abfrage erfolgt sofort, authorization_pending wird fortgesetzt, slow_down fügt fünf Sekunden hinzu, jeder andere Fehler endet mit der Beschreibung des Providers, und die Frist löst "Device authorization expired. Start a new flow." aus. Der Verifier sendet kein scope für Sie und es gibt keine automatische Erneuerung: Der Token-Speicher ist eine Datei im Home-Verzeichnis (.mcpfusion/token.json, Modus 0600, mit einem icacls-Fallback unter Windows). Behandeln Sie ihn als lokalen Einbenutzer-Standard und richten Sie für einen gehosteten Konnektor eigene Persistenz ein.

requireAuth() prüft die Existenz eines Tokens, nicht dessen Gültigkeit. Kombinieren Sie es mit requireJwt, wenn das Upstream-Token kryptografisch geprüft werden muss.

Hinweise für die Produktion

  • Bevorzugen Sie Plattform-Credentials gegenüber Benutzertokens für Server-zu-Server-Aufrufe: Deklarieren Sie sie mit defineCredentials und lesen Sie sie mit requireCredential. Siehe Credentials.
  • Rufen Sie auf Vinkius Cloud mit einem Verbindungstoken auf und verwenden Sie Connection Tokens in der Konsole, um den Zugriff pro Client zu widerrufen.
  • Auth-Middleware lässt sich mit der restlichen Kette kombinieren: Platzieren Sie sie außen, damit nicht autorisierte Aufrufe nie die Validierung erreichen, wie unter Middleware and context gezeigt.

Nächste Schritte