Zum Hauptinhalt springen

MCP-Authentifizierung

Der MCP Server spricht OAuth 2.1 mit PKCE über einen HTTP-Transport (Streamable HTTP). Er ist stateless: keine In-Memory-Session-Map, keine Sticky Sessions, kein Per-Client-Transport-State. Der State liegt in Firestore, der Client trägt ein Bearer-JWT.

Workspace Gate

Nur Google-Identitäten aus der cloudpilots.com-Workspace dürfen sich einloggen. Das Gate hängt am hd-Claim (Hosted Domain) des Google-ID- Tokens und wird gegen MCP_ALLOWED_DOMAIN geprüft (Default cloudpilots.com). Ein Email-Suffix-Check kommt bewusst nicht zum Einsatz — Service-Account-Tokens haben keinen hd-Claim und werden korrekt abgelehnt.

Token-Form

  • Access Token: RS256 JWT, 15 Minuten TTL. iss und aud zeigen beide auf MCP_PUBLIC_URL. Public Keys liegen unter /.well-known/jwks.json (1 h Cache auf Verifier-Seite).
  • Refresh Token: opak, 30 Tage TTL mit einem 30-Sekunden-Rotation- Grace-Window (das expiresAt des alten Tokens wird beim Rotate geschrumpft, nicht gelöscht — damit ein gleichzeitig fliegender Request nicht abschmiert).
  • Resource Indicator (RFC 8707): jeder /authorize- und /token- Request muss resource=<MCP_PUBLIC_URL> mitschicken. Ein Trailing Slash wird toleriert.

Discovery-Endpoints

Alle direkt unter der Server-Root:

EndpointLiefert
/.well-known/oauth-authorization-serverRFC-8414-Metadata (authorization_endpoint, etc.)
/.well-known/oauth-protected-resourceRFC-9728-Resource-Metadata
/.well-known/jwks.jsonAktive Signing-Keys (RS256)

Audit Log

Jeder Tool-Aufruf schreibt eine strukturierte JSON-Zeile nach stdout mit channel: "mcp_audit". Drin stehen uid, clientId, Tool-Name, Start / Ende, Dauer, Success / Failure und bei Erfolg die Pipeline-IDs. Was nicht drin steht: User-Prompt-Inhalte — die wären PII, und ein Routine-Log ist nicht der richtige Ort dafür.

Quoten

Per-uid Sliding-Window-Counter in Firestore:

LimitDefaultEnv Var
Stündliche Generations10MCP_HOURLY_QUOTA
Tägliche Generations60MCP_DAILY_QUOTA

Quota-Errors kommen als 429-artige Tool-Errors zurück und sollten vom Claude-Client dem User angezeigt werden, statt still im Hintergrund nachzuziehen.