# Security & Autorisierung: Vertrauensketten für MCP

> Sichere MCP-Server gegen unklare Provenance, untrusted Tool-Inhalte, falsche Token-Audiences, unsichere OAuth-Flows und Secret-Leaks ab.

Track: [MCP Engineering](https://physar.tech/learn/mcp-engineering)  
Kanonische Fassung: https://physar.tech/learn/mcp-engineering/security-authorization  
Stand: 2026-07-26  
Interaktiver Teil: 11 Checks (nur im Browser)

## MCP absichern: Vertrauen, Delegation und Geheimnisse an der richtigen Grenze

### Sicherheit beginnt vor der ersten MCP-Nachricht

Ein MCP-Server ist nicht nur ein Protokollendpunkt. Er kann lokal als Prozess mit den Rechten des Clients starten oder remote Kontext, Tool-Beschreibungen und Seiteneffekte anbieten. Deshalb beantwortet erfolgreiche Initialisierung nur eine Interoperabilitätsfrage. Sie beweist weder, dass der ausgelieferte Code erwartet ist, noch dass seine Aussagen oder Aktionen für den aktuellen Nutzer zulässig sind.

Dieses Modul betrachtet drei getrennte Vertrauensketten: **Software-Lieferkette** für den Server, **Inhalts- und Aktionsgrenze** für seine MCP-Antworten sowie **delegierte Autorisierung** für HTTP-Server. Werden sie vermischt, entsteht eine gefährliche Abkürzung: Ein technisch erreichbarer Server oder ein vorhandenes Token wird fälschlich als Freigabe gelesen.

_[Abbildung: Provenance, Autorisierung und untrusted Content sind getrennte Grenzen mit unterschiedlichen Kontrollen.]_

> **Leitfrage:** Welche Tatsache ist hier wirklich belegt: Herkunft des Servers, Zulässigkeit einer Aktion oder Berechtigung eines Tokens?

### Provenance ist eine Lieferkettenentscheidung

Vor allem ein lokaler `stdio`-Server führt Code im Sicherheitskontext des Clients aus. Ein Transportvertrag schützt nicht davor, dass eine Konfiguration auf ein manipuliertes Paket, einen unerwarteten Startbefehl oder einen fremden Release zeigt. Onboarding braucht daher einen nachvollziehbaren Pfad von verantwortlichem Herausgeber über überprüften Artefaktstand bis zur konkreten Freigabe im Produkt.

|  |  |
| --- | --- |
| Protokoll-Compliance | Der Endpoint spricht MCP; das sagt nichts über Herausgeber oder Codeinhalt aus. |
| Provenance | Herkunft, Review und die konkret freigegebene Auslieferung sind nachvollziehbar. |
| Laufzeitbegrenzung | Sandbox, minimale Rechte und sichtbarer Start begrenzen Schaden, falls Vertrauen fehlschlägt. |

Eine Organisation kann dafür etwa eine kuratierte Serverliste, einen Release-Review und eine unveränderliche Artefaktreferenz kombinieren. Das konkrete Werkzeug ist austauschbar. Wesentlich ist, dass ein Name, ein Registry-Eintrag oder eine erfolgreiche Capability-Verhandlung keine Freigabe ersetzt.

> **Grenze:** Bei Ein-Klick-Konfiguration muss der Client den tatsächlich ausgeführten Befehl und seine Wirkung sichtbar machen; stilles Starten ist keine vertrauenswürdige Installation.

### Tool-Metadaten sind Hinweise, keine Rechte

Tool-Namen, Beschreibungen, Schemas, Resource-Inhalte und Server-Instructions kommen über eine Servergrenze. Selbst wenn sie korrekt formatiert sind, dürfen Host und Modell sie nicht als Wahrheit oder Policy behandeln. Ein freundlicher Tool-Name kann eine breite Wirkung verbergen; ein aus einer Resource gelesener Text kann eine Aufforderung enthalten, die gar nicht zur Nutzeraufgabe gehört.

|  |  |
| --- | --- |
| Metadata und Annotation | Orientierung für Oberfläche und Modell, aber keine selbst erteilte Berechtigung. |
| Host-Policy | Erlaubt oder verbietet Server, Tool, Parameterbereich und Interaktionszeitpunkt. |
| Serverseitige Autorisierung | Prüft Identität und Rechte erneut, bevor eine geschützte Wirkung erfolgt. |

Annotations können UX und Risikoeinschätzung verbessern, etwa als Hinweis auf mögliche Seiteneffekte. Sie ändern aber weder die Produktpolicy noch die serverseitige Durchsetzung. Der Host hält Herkunft sichtbar, begrenzt Kontext und verlangt bei riskanten Vorgängen eine passende Freigabe außerhalb der Modellentscheidung.

> **Merksatz:** Beschreibungen erklären eine Capability. Nur Policy und Autorisierung erlauben ihre Nutzung.

**Kurzcheck:** Ein zugelassener Server beschreibt sein Tool als ungefährlich, doch es sendet Kundendaten an einen externen Dienst. Was entscheidet, ob der Host es zeigt oder ausführt?

- [x] Die lokale Host-Policy prüft Herkunft, Zweck, Datenweitergabe und konkrete Parameter; bei Risiko verlangt sie eine passende Freigabe.
- [ ] Die Annotation `readOnlyHint`, weil sie den Seiteneffekt bereits verbindlich klassifiziert.
- [ ] Das Modell, weil es die Tool-Beschreibung im Kontext beurteilen kann.

> Genau. Server-Metadaten erklären nur eine Behauptung. Die durchsetzbare Entscheidung bleibt bei Host-Policy, Consent und serverseitiger Autorisierung.

### HTTP-Autorisierung folgt einer Entdeckungskette

Die MCP-Autorisierung gilt für HTTP-basierte Transports. Der geschützte MCP-Server ist dabei OAuth Resource Server, der MCP-Client handelt im Namen des Resource Owners, und ein Authorization Server stellt Tokens aus. Für `stdio` beschreibt die MCP-Spezifikation diesen Flow ausdrücklich nicht; Credentials werden dort aus der lokalen Umgebung bezogen und müssen als eigene lokale Sicherheitsgrenze behandelt werden.

Geschützten MCP-Endpoint anfragen → Bei Challenge Protected Resource Metadata bestimmen → **Metadata-`resource` gegen den angefragten MCP-Endpoint prüfen** → Darin benannten Authorization Server und dessen Metadaten entdecken → Passende Client-Registrierung und Redirect-URI wählen → Autorisierung mit Resource Indicator, PKCE und State durchführen → Token nur zum vorgesehenen MCP-Server senden → Server validiert Token und berechtigt die konkrete Operation

Die Discovery-Dokumente sind selbst Netzwerkdaten. Ein Client prüft daher HTTPS, URL-Schema, Ziel- und Netzwerkpolicy und verwirft Protected Resource Metadata, deren `resource` nicht zum tatsächlich angefragten MCP-Endpoint passt. Er folgt ihnen nicht blind in interne Netze oder in eine Shell. Die Discovery beantwortet, wo ein Authorization Server beschrieben ist; sie hebt keine Trust-Policy für einen bisher unbekannten Server auf.

> **Nicht verwechseln:** Session-ID, Transportverbindung und Access Token haben verschiedene Aufgaben. Eine Session authentisiert keinen Request von selbst.

### Resource Indicator und Audience binden Delegation

Ein OAuth Access Token ist keine allgemeine Nutzeridentität. Bei MCP enthält die Autorisierungs- und Token-Anfrage den `resource`-Parameter für die kanonische URI des angesprochenen MCP-Servers. So kann der Authorization Server ein Token für genau diese Ressource ausstellen. Der Resource Server prüft anschließend Signatur oder Introspection, Ablauf, Aussteller und insbesondere, ob er selbst die vorgesehene Audience ist.

|  |  |
| --- | --- |
| Resource Indicator | Absicht des Clients beim Token-Bezug: für welchen MCP-Server wird Zugriff angefragt? |
| Audience-Validierung | Prüfung des Servers: wurde dieses Token für mich ausgestellt? |
| Token Passthrough | Ein fremdes Upstream-Token wird weitergereicht; das durchbricht die Empfängerbindung und ist im MCP-Flow unzulässig. |

Ein Server darf weder Tokens für andere Ressourcen akzeptieren noch solche Tokens durch sich hindurchreichen. Das bleibt auch dann falsch, wenn derselbe Nutzer beide Systeme verwenden darf. Jeder geschützte Server muss seine eigene Autorisierungskette und seine eigene Durchsetzung besitzen.

> **Fehlerbild:** Ein Token mit gültiger Signatur, aber falscher Audience ist für diesen MCP-Server kein gültiger Zugang.

### Client-Registrierung wird ausgehandelt, nicht erfunden

Für unbekannte Gegenstellen können Client ID Metadata Documents die Client-Identität über ein HTTPS-Dokument beschreiben. Bei bestehender Beziehung gibt es vorregistrierte Client-Daten. Dynamic Client Registration ist eine weitere, aber optionale Möglichkeit. Der Client wählt nur einen Weg, den die Metadaten und die Zugangspolitik des konkreten Authorization Servers unterstützen.

- **Vorregistrierung**: verwende bekannte Client-Daten, wenn eine belastbare Beziehung besteht.
- **Client ID Metadata Document**: nutze es nur, wenn der Authorization Server diese Form unterstützt und Dokument, Client-ID sowie Redirect-URIs konsistent validierbar sind.
- **Dynamic Client Registration**: nur bei angekündigtem Registration Endpoint und einer Policy, die diese Registrierung zulässt.
- **Kein verfügbarer Weg**: zeige einen kontrollierten Konfigurations- oder Abbruchpfad statt unausgesprochene Annahmen zu hard-coden.

Registrierung ist keine pauschale Vertrauenszusage. Besonders bei Proxies müssen Consent und Clientidentität pro delegierter Beziehung nachvollziehbar bleiben, damit ein statischer Upstream-Client nicht zur unbemerkten Stellvertretung für beliebige Downstream-Clients wird.

> **Merksatz:** Metadata Discovery sagt, welche Registrierung möglich ist; die eigene Trust-Policy entscheidet, welche unbekannte Identität akzeptabel ist.

### PKCE und State schützen den Rückweg

Öffentliche Clients können ein Client Secret nicht zuverlässig geheim halten. Im Authorization-Code-Flow erzeugen sie daher pro Vorgang einen kryptografisch zufälligen `code_verifier`, senden davon die `S256`-abgeleitete Challenge zur Autorisierungsanfrage und verwenden den Verifier nur beim Token-Austausch. Ein abgefangener Authorization Code genügt ohne den Verifier nicht für den Token-Bezug.

Neue Nutzeraktion erhält korrelierten State → Client erzeugt frischen PKCE Verifier und S256 Challenge → Authorization Request enthält Resource, Redirect-URI, State und Challenge → Authorization Server leitet zurück → **Client prüft State und genaue Redirect-Zuordnung** → Token Request enthält denselben Resource Indicator und den geheim gehaltenen Verifier

State korreliert die Rückkehr mit der gestarteten Nutzeraktion und wird vor jeder weiteren Verarbeitung geprüft, kurzlebig gespeichert und genau einmal verbraucht. PKCE und State lösen verschiedene Probleme: PKCE bindet den Code-Austausch an den ursprünglichen Clientvorgang; State wehrt vertauschte, eingeschleuste oder alte Browser-Rückgaben ab. Beide Werte sind pro Flow gebunden.

> **Abbruchregel:** Fehlt die angekündigte PKCE-Unterstützung oder stimmt State nicht, beendet der Client den Flow. Ein Fallback ohne diese Schutzwirkung ist keine neutrale Kompatibilitätsentscheidung.

### Consent und Scopes delegieren nur eine konkrete Aufgabe

Scopes machen Berechtigungen prüfbar, sind aber keine Ersatzsprache für Geschäftsregeln. Der Server modelliert eine kleine, verständliche Scope-Oberfläche und prüft zusätzlich Ressource, Mandant, Objekt und Aktion. Der Client beginnt mit den für die aktuelle Aufgabe erforderlichen Rechten oder folgt einer präzisen Challenge. Für eine später benötigte privilegierte Aktion fordert er gezielt eine Stufenerhöhung an.

|  |  |
| --- | --- |
| Initiale Delegation | Benötigt nur die minimale, für Discovery oder den aktuellen Workflow passende Berechtigung. |
| Step-up | Eine konkrete Operation scheitert mit unzureichendem Scope; der Client erklärt und fordert nur die notwendige Erweiterung an. |
| Serverdurchsetzung | Prüft Scope plus fachliche Berechtigung bei jeder Wirkung; ein Scope gewährt nicht automatisch jede Datenansicht. |

Consent muss die delegierte Wirkung verständlich machen: welcher Client erhält für welchen Server welche Zugriffsklasse und warum jetzt. Ein breiter, unbegrenzt wiederverwendbarer Sammelscope senkt zwar Dialoge, vergrößert aber Schaden bei Tokenverlust und verschlechtert Auditierbarkeit.

> **Praxisregel:** Eine 403-Antwort mit präziser Scope-Challenge ist ein Autorisierungszustand, kein Signal für endlose automatische Wiederholungen.

### Redirect-URIs sind feste Rückgabeadressen

Die Redirect-URI bestimmt, wohin Authorization Code und State zurückkehren. Authorization Server vergleichen sie exakt mit einer registrierten URI; Platzhalter, Host-Präfixe, offene Weiterleitungen oder ein nur ähnlicher Pfad erlauben Code-Diebstahl. Der Client registriert nur die Rückgabeadressen, die er tatsächlich kontrolliert, und validiert seine eigene Rückgabe ebenfalls gegen den gestarteten Flow.

- **Exakter Vergleich**: Scheme, Host, Port, Pfad und Query müssen zur vollständig registrierten URI passen.
- **Jede Rückgabeadresse einzeln registrieren**: eine zusätzliche URL ist keine Variante einer vorhandenen Registrierung.
- **Keine offene Weiterleitung**: ein Query-Parameter darf den Browser nicht zu einem beliebigen Ziel umleiten.
- **Sichere Anzeige und Öffnung**: URLs aus der Autorisierung werden geparst, auf erlaubte Schemes begrenzt und nicht über eine Shell gestartet.
- **Lokale Sonderfälle bewusst behandeln**: Loopback-Redirects sind eine andere Risikoklasse und benötigen klare Plattform- und Nutzerwarnungen.

> **Merksatz:** Die Redirect-URI ist kein Komfort-Callback, sondern ein Teil der Clientidentität und des Code-Schutzes.

### Secrets dürfen keine MCP-Inhalte werden

Passwörter, API-Schlüssel, Refresh Tokens und andere langlebige Credentials gehören weder in Prompt-Argumente noch in Tool-Beschreibungen, Resource-Inhalte, Modellkontext, URLs oder unredigierte Logs. Ein einmal als MCP-Content zurückgegebenes Secret kann in Gesprächsverläufe, Telemetrie, Support-Exports oder nachgelagerte Modelle gelangen und ist kaum noch zuverlässig zurückzuholen.

|  |  |
| --- | --- |
| Token und Secret speichern | Nur in einer dafür vorgesehenen, zugriffsbeschränkten Credential-Ablage; Zugriff ist an Identität und Zweck gebunden. |
| MCP-Request und Tool-Output | Nur Referenzen, Status oder redigierte Fehler; niemals den Secret-Wert transportieren. |
| Logging und Tracing | Sensitive Felder vor Persistenz maskieren; Zugriff, Aufbewahrung und Incident-Prozess bewusst festlegen. |

Wenn ein Server eine geheime Eingabe benötigt, darf er sie nicht als scheinbar harmlosen Freitext über Modell oder Tool einfordern. Der sichere Weg ist eine passende Credential- oder Autorisierungsinteraktion außerhalb des Modellkontexts. Bei Verdacht auf Leak werden Credentials widerrufen oder rotiert und betroffene Logs nach dem Incident-Verfahren behandelt.

> **Merksatz:** Redaktion in Logs ist wichtig, aber kein Ersatz dafür, Secrets gar nicht erst in den MCP-Datenfluss zu geben.

### Eine Sicherheitsentscheidung bleibt über den gesamten Lifecycle wirksam

Serverherkunft und Startkonfiguration prüfen → Server und Capabilities per Host-Policy zulassen → Tool-Inhalte und Metadaten als untrusted behandeln → Bei HTTP Resource und Authorization Server kontrolliert entdecken → Registrierung, Redirect, State und PKCE pro Flow absichern → **Token für Zielresource ausstellen und Audience am Server prüfen** → Scopes und Consent auf konkrete Wirkung begrenzen → Secrets aus MCP-Content und Telemetrie fernhalten → Änderungen, Widerruf und Incidents betreiben

Die folgenden neun Checks sind absichtlich keine Checkliste für eine einzelne OAuth-Bibliothek. Sie trennen Provenance von Protokoll-Compliance, Hinweise von Berechtigungen, Discovery von Vertrauen und Tokenbesitz von zulässiger Delegation. Entscheidend ist jeweils, welche Grenze ein Vorschlag gerade auslässt.

- **Serververtrauen**: Herkunft und Ausführungsrechte vor der Verbindung begrenzen.
- **Autorisierungsfluss**: Resource, Audience, Registrierung, PKCE, State und Redirect konsistent verbinden.
- **Datenhygiene**: Consent, Scopes und Secrets so gestalten, dass ein einzelner Fehler begrenzten Schaden anrichtet.

> **Ausblick:** Im Betriebsmodul werden diese Verträge getestet, beobachtet und über Änderungen hinweg abgesichert. Hier definierst du die Sicherheitsinvarianten, die dort überprüfbar bleiben müssen.

## Quellen

- modelcontextprotocol.io/specification/2025-11-25/basic/authorization — https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization
- modelcontextprotocol.io/specification/2025-11-25/basic/transports — https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- modelcontextprotocol.io/specification/2025-11-25/server/tools — https://modelcontextprotocol.io/specification/2025-11-25/server/tools
- modelcontextprotocol.io/docs/tutorials/securit…urity_best_practices — https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices
- rfc-editor.org/rfc/rfc8707 — https://www.rfc-editor.org/rfc/rfc8707
- rfc-editor.org/rfc/rfc7636 — https://www.rfc-editor.org/rfc/rfc7636
- rfc-editor.org/rfc/rfc8252 — https://www.rfc-editor.org/rfc/rfc8252
- rfc-editor.org/rfc/rfc9728 — https://www.rfc-editor.org/rfc/rfc9728
- rfc-editor.org/rfc/rfc7591 — https://www.rfc-editor.org/rfc/rfc7591
