Zum Inhalt springen

MCP

Steuerung von MCP-Servern mit RFC 9728 und RFC 8707 – was tatsächlich funktioniert

Von Olivares AI 10 min Lesezeit

Sie verbinden Claude Code mit einem MCP-Server. Der Server erfordert eine Authentifizierung. Ihr Kunde sendet eine Anfrage; Der Server antwortet mit einem 401 Unauthorized- und einem WWW-Authenticate: Bearer-Header, der eine resource_metadata-URL enthält. Was als nächstes passiert, ist ein OAuth 2.1-Flow, der durch drei RFCs und eine Reihe von MCP-spezifischen Erweiterungen definiert wird, die zusammengenommen eines der schwierigeren Probleme der Agentensicherheit lösen: Sicherstellen, dass ein Token, das für die Kommunikation mit diesem MCP-Server erhalten wurde, nicht gegen diesen Server abgespielt werden kann.

In diesem Beitrag wird der gesamte Ablauf nachgezeichnet – was die Spezifikation sagt, was die RFCs tatsächlich bieten und wo sich in der Praxis Sicherheitslücken verbergen.

Der Fluss: von 401 zu einem ressourcengebundenen Token

Das MCP-Autorisierungsmodell (Revision 2025-11-25, unverändert in den Release Candidate übernommen – eingefroren am 2026-05-21 – für die endgültige Spezifikation, die für den 2026-07-28 geplant ist) ist ein zweiphasiger Prozess. Phase 1 ist die Erkennung: Der 401 mit WWW-Authenticate: Bearer resource_metadata="..." teilt dem Client mit, dass dieser Server durch OAuth geschützt ist und wo seine Metadaten zu finden sind. Phase 2 ist der autorisierte Zugriff: Metadaten konsumieren, den Autorisierungsserver ermitteln, ein an diesen bestimmten Server gebundenes Token erhalten und es verwenden.

Die konkreten Schritte:

  1. 401 + WWW-Authenticate: Der MCP-Server lehnt eine nicht authentifizierte Anfrage ab. Der Parameter resource_metadata in der Challenge verweist auf das Protected Resource Metadata-Dokument des Servers.

  2. PRM-Abruf (RFC 9728): Der Client ruft die /.well-known/oauth-protected-resource-URL ab. Die Antwort ist ein JSON-Dokument, das den kanonischen Ressourcen-URI des Servers, die Autorisierungsserver, die ihn schützen, und die von der Ressource unterstützten Bereiche deklariert. Der Client überprüft, ob das Feld resource des Dokuments mit dem Server übereinstimmt, den es erreichen soll. Eine Nichtübereinstimmung ist ein Signal für einen Identitätswechsel und muss zurückgewiesen werden.

  3. AS-Erkennung (RFC 8414): Mithilfe der Aussteller-URL aus dem authorization_servers-Array des PRM durchläuft der Client die bekannten Kandidaten (/.well-known/oauth-authorization-server, dann /.well-known/openid-configuration), um die Metadaten des Autorisierungsservers abzurufen. Der Aussteller im zurückgegebenen Dokument muss byte-identisch mit dem Aussteller sein, für den es abgerufen wurde – nicht „äquivalent nach der Normalisierung“ und nicht „nahe genug“. Byteidentisch.

  4. Token-Erwerb (RFC 8707): Der Client fordert ein Token vom Token-Endpunkt des AS an, einschließlich resource=<canonical server URI> sowohl in den Autorisierungs- als auch in den Token-Anfragen. Dadurch wird die Zielgruppe des Tokens an diesen bestimmten MCP-Server gebunden. Der AS gibt ein Token aus, dessen Zielgruppe diese Ressource ist, und der Client präsentiert es dem Server.

  5. Autorisierter Zugriff: Der Client verwendet das Token, um die schreibgeschützten Selbstprüfungsmethoden des MCP-Servers aufzurufen (tools/list, resources/list usw.). Der Token beweist, dass der Kunde autorisiert ist; Der Ressourcenindikator beweist, dass das Token für diesen Server geprägt wurde.

Was RFC 9728 tatsächlich bietet

RFC 9728 (Protected Resource Metadata) ist ein Erkennungsmechanismus. Die Antwort lautet: „Welcher Autorisierungsserver schützt diese Ressource und was erwartet er?“ Der Server wird nicht authentifiziert, das Token wird nicht validiert und die Zugriffskontrolle wird nicht erzwungen. Das sind getrennte Anliegen.

Das PRM-Dokument verfügt über ein erforderliches Feld (resource) und eine Reihe optionaler Felder, von denen authorization_servers am wichtigsten ist. Die Spezifikation MCP verschärft die Optionalität des RFC: Es ist mindestens ein Autorisierungsserver erforderlich. Ein PRM-Dokument, in dem keine aufgeführt sind, wird als Fehler behandelt.

Das Feld resource ist der kanonische URI der geschützten Ressource. Der Client muss es mit dem Server vergleichen, den er kontaktieren wollte, und eine Nichtübereinstimmung ablehnen:

// RFC 9728 §3.3: Der Ressourcenwert des PRM MUSS den Geschützten identifizieren
// Ressource, die der Client anspricht – einfacher String-Vergleich mit
// Der Ressourcenindikator, an den dieser Client seine Token bindet.
if prm.Resource != c.resource {
    return authServerMetadata{}, fmt.Errorf(
        "mcp: oauth: protected resource metadata declares resource %q, "+
        "expected %q (RFC 9728 §3.3 reject)", prm.Resource, c.resource)
}

Diese Prüfung verhindert eine Art von Angriff, bei dem ein böswilliges oder falsch konfiguriertes PRM-Dokument vorgibt, für eine andere Ressource zu sprechen. Der Vergleich ist nicht normalisiert – es handelt sich um einen direkten String-Abgleich mit dem kanonischen Ressourcen-URI, den der Client für die ihm gegebene Server-URL berechnet hat.

RFC 8707-Ressourcenindikatoren – warum die Token-Bindung wichtig ist

Ohne Ressourcenindikatoren kann ein von einem AS erhaltenes Zugriffstoken potenziell auf jedem Ressourcenserver verwendet werden, den AS schützt. Wenn Sie zwei MCP-Server haben – beispielsweise einen schreibgeschützten Dokumentationsserver und eine Code-Ausführungs-Sandbox – beide hinter demselben Identitätsanbieter, könnte ein für den einen erhaltenes Token dem anderen präsentiert werden. Das ist ein verwirrtes Stellvertreterproblem.

RFC 8707 löst dieses Problem, indem den Autorisierungs- und Token-Anfragen ein Parameter resource hinzugefügt wird. Der AS gibt ein Token aus, dessen Zielgruppe explizit dieser Ressourcen-URI ist. Ein ordnungsgemäß validierender Ressourcenserver lehnt ein Token ab, dessen Zielgruppe nicht mit seiner eigenen Identität übereinstimmt.

In der Praxis enthält die Token-Anfrage neben der Gewährung auch den Ressourcenindikator:

form := url.Values{
    "grant_type": {"client_credentials"},
    "resource":   {c.resource}, // RFC 8707 — das Token an die Zielgruppe binden
}

Dies erscheint in jedem Gewährungstyp, den der Connector verwendet: Client-Anmeldeinformationen, Autorisierungscode-Einlösung und Aktualisierungstokenrotation. Der Ressourcenindikator ist nicht optional – er ist in jeder Token-Anfrage vorhanden, sodass jedes Token konstruktionsbedingt an die Zielgruppe gebunden ist.

Die byteidentische Emittentenprüfung

Die sicherheitskritischste Validierung im gesamten Ablauf ist auch am einfachsten anzugeben und am leichtesten zu verwechseln: Der Ausstellerwert im AS-Metadatendokument muss byte-identisch mit dem Aussteller sein, den der Client zum Erstellen der bekannten URL verwendet hat.

Nicht unabhängig von der Groß-/Kleinschreibung gleich. Nach Schemanormalisierung nicht gleichwertig. Nicht dasselbe nach dem Entfernen eines abschließenden Schrägstrichs. Byteidentisch. In Abschnitt 3.3 von RFC 8414 wird dies ausdrücklich erläutert, und die Spezifikation MCP übernimmt die Anforderung.

// discoverASMetadata: LEHNT ein Dokument ab, dessen issuer nicht
// BYTE-IDENTISCH mit dem issuer ist, für den es abgerufen wurde (RFC 8414 §3.3).
// Ein abweichendes Dokument ist ein Signal für Identitätsvortäuschung.
if as.Issuer != issuer {
    return authServerMetadata{}, fmt.Errorf(
        "mcp: oauth: AS metadata at %s declares issuer %q, "+
        "expected %q (RFC 8414 §3.3 reject)", cand, as.Issuer, issuer)
}

Warum so streng? Denn ein Angreifer, der DNS kontrolliert oder im Netzwerkpfad sitzt, kann ein Metadatendokument bereitstellen, das auf seinen eigenen Token-Endpunkt verweist, während er sich als legitimer Aussteller ausgibt. Wenn der Client den Aussteller vor dem Vergleich normalisieren würde, würden https://auth.example.com und https://AUTH.example.com übereinstimmen – und das Dokument des Angreifers würde akzeptiert. Der byteidentische Vergleich schließt dies ab.

Die gleiche Disziplin wird in RFC 9207 (Autorisierungsantwort-Ausstellervalidierung) übernommen. Wenn der Client einen Autorisierungscode-Fluss startet, zeichnet er den Aussteller aus den validierten AS-Metadaten auf. Bei der Rückumleitung muss der Parameter iss in der Antwort mit dem aufgezeichneten Wert übereinstimmen – wiederum Byte für Byte, keine Normalisierung – bevor der Autorisierungscode eingelöst wird. Dies ist die Verwechslungsverteidigung: Ohne sie könnte ein böswilliger AS den Code abfangen und den Client veranlassen, ihn am Token-Endpunkt des Angreifers einzulösen.

Kundenidentifikation: CIMD ersetzt DCR

Die MCP-Spezifikation definiert eine Prioritätsreihenfolge dafür, wie sich ein Client gegenüber dem Autorisierungsserver identifiziert:

  1. Vorregistrierte Anmeldeinformationen – der Betreiber stellt im Voraus einen client_id und einen client_secret bereit
  2. CIMD (Client-ID-Metadatendokumente) – der Client hostet ein JSON-Dokument unter einer HTTPS-URL; Diese URL ist client_id
  3. Dynamische Client-Registrierung (RFC 7591) – der Client registriert sich selbst am Registrierungsendpunkt des AS
  4. Den Benutzer auffordern – gilt nicht für Headless-Agenten

DCR ist im Release Candidate für die endgültige Spezifikation, die für den 2026-07-28 geplant ist, zugunsten von CIMD veraltet. Der Grund ist betriebsbedingt: DCR erstellt einen dauerhaften Clientstatus auf dem Autorisierungsserver. Jeder Agent, der sich selbst registriert, hinterlässt ein client_id/client_secret-Paar, das der AS speichern muss, und niemand verfolgt oder widerruft sie. Für eine Flotte von Agenten ist dies eine unkontrollierte Ausbreitung von Anmeldeinformationen.

CIMD invertiert das Modell. Der Client hostet ein Dokument unter einer von ihm kontrollierten URL. Der AS ruft das Dokument ab, wenn er den Client validieren muss, speichert es entsprechend den HTTP-Cache-Headern zwischen und speichert nichts dauerhaft. Bei der Schlüsselrotation handelt es sich um eine Dokumentenaktualisierung. Durch die Außerbetriebnahme eines Clients wird das Dokument entfernt. Bei der AS sammeln sich keine verwaisten Registrierungen an.

Der Kompromiss: CIMD erfordert, dass der Client einen HTTPS-Endpunkt ausführt. Für eine selbstgehostete Governance-Ebene ist das selbstverständlich – die Ebene führt bereits HTTPS-Dienste aus. Bei einem CLI-Tool auf einem Entwickler-Laptop ist dies weniger der Fall, weshalb vorregistrierte Anmeldeinformationen weiterhin die erste Option in der Prioritätsreihenfolge sind.

Eine CIMD-Identität kann kein gemeinsames Geheimnis tragen (die Dokument-URL ist öffentlich – ein darin enthaltenes Geheimnis würde ein Anmeldeinformationsleck darstellen). Die Client-Authentifizierung verwendet private_key_jwt (RFC 7523): Der Client signiert einen kurzlebigen JWT mit einem privaten Schlüssel, dessen öffentliches Gegenstück im jwks-Feld des CIMD-Dokuments veröffentlicht wird.

Die „Niemals passieren“-Regel

Eine strukturelle Abwehr, die leicht zu übersehen ist: Der Connector verwendet immer nur ein Token, das er selbst für einen bestimmten Server durch den oben beschriebenen Erkennungsablauf erhalten hat. Es akzeptiert niemals ein Token von einem Dritten und leitet es an einen MCP-Server weiter. Es liest niemals ein Token aus einer eingehenden Anfrage und leitet es weiter.

Dies ist die verwirrte stellvertretende Verteidigung auf Protokollebene. Wenn ein Client empfangene Token weiterleitet, könnte ein Angreifer ein Token präsentieren, das auf eine Ressource mit niedrigen Privilegien beschränkt ist, und den Client veranlassen, es an eine Ressource mit hohen Privilegien weiterzuleiten (oder umgekehrt – extrahieren Sie ein Token mit hohen Privilegien, indem Sie den Client dazu verleiten, es einem vom Angreifer kontrollierten Server zu präsentieren). Indem der Stecker seine eigenen Token erhält und niemals die von anderen berührt, kann er nicht als Token-Relais fungieren.

Von Token-Passthrough wird nicht nur abgeraten – es ist strukturell unmöglich. Der HTTP-Client des Connectors für OAuth-Flows ist von allen eingehenden Anforderungshandlern getrennt. Es gibt keinen Codepfad, der ein Bearer-Token aus einer eingehenden Anfrage liest und in eine ausgehende Anfrage schreibt.

SSRF: die DNS-Rebinding-Verteidigung

Alle Metadaten und Token-Endpunkt-URLs, die der Connector abruft, werden auf zwei Ebenen durch SSRF geschützt. Die erste ist eine Prüfung vor dem Flug: Die URL muss HTTPS sein (außer Loopback für die lokale Entwicklung) und darf keine buchstäblich reservierte IP-Adresse sein.

Bei der zweiten handelt es sich um eine Wählzeitprüfung, die das DNS-Rebinding-TOCTOU schließt. Ein Hostname, der während der Prüfung vor dem Flug in eine öffentliche IP-Adresse aufgelöst wird, kann sich beim Anwählen des Sockets erneut an eine private IP-Adresse binden. Der HTTP-Client des Connectors installiert eine net.Dialer.Control-Funktion, die die konkret aufgelöste IP zum Zeitpunkt der Verbindung überprüft und jede reservierte Adresse ablehnt. Dies ist die maßgebliche Prüfung – die Vorflugprüfung ist in offensichtlichen Fällen eine schnelle Zurückweisung, aber die Einwahlzeitprüfung ist diejenige, die zählt.

Erweiterung des Umfangs

Ein MCP-Server kann eine Anfrage mit WWW-Authenticate: Bearer error="insufficient_scope" scope="mcp:tools:list mcp:resources:read" beantworten. Die Spezifikation (SEP-835/SEP-2350) definiert, wie der Client damit umgeht: Berechnen Sie die Vereinigung der Bereiche, die er zuvor angefordert hat, und der Bereiche, die der Server gerade abgefragt hat, und fordern Sie dann erneut ein Token mit diesem erweiterten Satz an. Die Union behält zuvor erteilte Berechtigungen bei und fügt die neuen hinzu. Die Erhöhung erfolgt einmal – eine zweite Herausforderung mit unzureichendem Umfang für dieselbe Anfrage wird nicht wiederholt, um Endlosschleifen zu verhindern.

Der Server darf bei seiner Herausforderung zustandslos sein: Er benennt nur die Bereiche, die der aktuelle Vorgang benötigt, nicht den vollständigen Satz, den der Client möglicherweise zuvor angefordert hat. Durch die clientseitige Akkumulation funktioniert dies, ohne dass der Server den Bereichsverlauf pro Client verfolgt.

Was das in der Praxis bedeutet

Der OAuth-Ablauf für MCP-Server ist gut spezifiziert und befasst sich bei strikter Implementierung mit den tatsächlichen Angriffsflächen: Token-Wiedergabe über Server hinweg, Metadaten-Identitätswechsel, DNS-Rebinding-SSRF und unkontrollierte Ausbreitung von Client-Anmeldeinformationen. Die byteidentische Emittentenprüfung, der Ressourcenindikator in jeder Token-Anfrage und die strukturelle No-Passthrough-Regel sind die wichtigsten Abwehrmaßnahmen. Dabei handelt es sich nicht um Funktionen, die man zur Hälfte implementieren kann – jede einzelne davon ist eine harte Prüfung, die nicht abgeschlossen werden kann.

Das schwierigere Problem ist betrieblicher Natur. Teams, die MCP-Server bereitstellen, müssen:

  • Veröffentlichen Sie ein gültiges PRM-Dokument unter /.well-known/oauth-protected-resource mit einem resource-Feld, das dem kanonischen URI ihres Servers entspricht
  • Verwenden Sie einen AS, der Ressourcenindikatoren unterstützt – viele Identitätsanbieter tun dies immer noch nicht oder behandeln den Parameter resource eher als Empfehlung denn als Zielgruppenbindung
  • Wechseln Sie von DCR zu CIMD, bevor die Einstellung zu einer Entfernung wird, oder registrieren Sie die Anmeldeinformationen explizit vor
  • Anmeldeinformationen an einen Aussteller anpinnen, um eine stille ausstellerübergreifende Wiederverwendung zu verhindern, wenn sich die AS-Topologie ändert

Die MCP-Connector-Dokumentation deckt die Betriebskonfiguration ab, und das Sicherheitsmodell beschreibt, wie das ressourcengebundene Token in die breitere Access Map passt.

Verwandte Beiträge

Häufige Fragen

Garantiert RFC 9728, dass der MCP-Server, mit dem ich kommuniziere, legitim ist?

Nein. Mit RFC 9728 kann der Client herausfinden, welcher Autorisierungsserver eine Ressource schützt und welche Bereiche er benötigt. Dabei handelt es sich jedoch um Metadaten über die Ressource und nicht um einen Nachweis der Identität der Ressource. Ein TLS-Zertifikat beweist den Hostnamen des Servers; PRM erklärt Ihnen, wie Sie sich authentifizieren. Die beiden ergänzen sich: PRM ohne TLS-Verifizierung ist eine Entdeckung gegen einen nicht verifizierten Host, und TLS ohne PRM lässt den Client rätseln, wie er ein Token erhält.

Warum ist die dynamische Client-Registrierung in der MCP-Spezifikation veraltet, wenn sie immer noch funktioniert?

DCR erstellt einen dauerhaften Client-Status auf dem Autorisierungsserver – ein client_id und client_secret, den der AS speichern und verwalten muss. Für eine Flotte kopfloser Agenten stellt dies ein Problem der unkontrollierten Ausbreitung von Anmeldeinformationen dar: Jeder Agent registriert sich selbst, und niemand verfolgt oder rotiert diese Registrierungen. CIMD (Client-ID-Metadatendokumente) ersetzt dies durch ein gehostetes Dokument, das der Client steuert und das der AS bei Bedarf abruft – kein dauerhafter Status beim AS, keine verwaisten Registrierungen und die Schlüsselrotation ist eine Dokumentaktualisierung und keine erneute Registrierung.

Sehen Sie, worauf Ihre Agenten zugreifen können

Olivares AI ist die offene, selbstgehostete Plattform für Ihre KI-Landschaft. Betreiben Sie sie auf Ihrer eigenen Infrastruktur und erhalten Sie die Zugriffskarte, nach der Ihre Security- und Platform-Teams seit Langem fragen.