BlogKI
Warum sich Benutzer an unserem Remote-MCP-Server mit Entra ID anmelden, nicht mit Tokens
PATs funktionieren für einen MCP-Server, aber die IT im Unternehmen kann sie nicht steuern. Wie bei uns die Entra ID des Kunden den Zugang regelt.
Für ein Unternehmen ist an einem MCP-Server nicht die spannende Frage, welche Tools er anbietet. Sie lautet: Wer in unserer Organisation darf ihn nutzen, mit welchem KI-Assistenten, und wie schalten wir das wieder ab?
Diese Frage mussten wir für time cockpit beantworten, unser Produkt für Zeiterfassung und Projektcontrolling. Die Web API arbeitet bereits mit Personal Access Tokens, und sie für den neuen MCP-Server wiederzuverwenden, war der naheliegende Weg. Wir haben uns dagegen entschieden. Was wir stattdessen gebaut haben, hat rund vier Monate Kalenderzeit gedauert: vom ersten Entra-Prototyp im Mai bis zu einem Setup, das wir im September mit fünf KI-Clients dokumentieren und testen konnten. Dieser Artikel erklärt, warum wir den längeren Weg gegangen sind und was er der IT des Kunden bringt.
Der naheliegende Weg: das Access Token wiederverwenden
Die Web API von time cockpit authentifiziert mit Personal Access Tokens (PATs). Ein Benutzer erstellt eines, legt fest, wie lange es gültig ist, und mit dem Data-Scope hat es dieselben Berechtigungen, die der Benutzer im Produkt hat. Für Skripte und Integrationen ist das das richtige Werkzeug.
Ein MCP-Server könnte dasselbe Token als Bearer Token akzeptieren. Ob das funktioniert, hängt vom KI-Client ab:
- Die Entwicklerwerkzeuge können eines mitschicken. Claude Code nimmt es als Header (
--header "Authorization: Bearer …"), Codex liest es aus einer Umgebungsvariable (bearer_token_env_var), und VS Code trägt es in dieheadersseinermcp.jsonein. - ChatGPT kann es nicht. Laut der Apps-SDK-Dokumentation von OpenAI kann ChatGPT keine eigenen API-Keys mitschicken; es erwartet OAuth oder gar keine Anmeldung.
- Die Claude-App unterstützt ein festes Token nur als Beta und für ausgewählte Organisationen. Ein Owner der Organisation trägt es einmal ein, und Claude schickt danach dieselben Zugangsdaten für jedes Mitglied. Das PAT einer einzelnen Person würde für die ganze Organisation handeln.
Ein PAT würde also nicht einmal jeden Assistenten erreichen, den unsere Kunden verwenden. Und wo es ihn erreicht, scheitert es im Unternehmen an vier Punkten:
- Das Geheimnis landet an Orten, die die IT nicht kontrolliert. Ein PAT ist langlebig und liegt in einer Konfigurationsdatei oder Umgebungsvariable auf jedem Rechner, auf dem jemand einen Assistenten verbunden hat. Bis es abläuft, trägt es die vollen Berechtigungen des Benutzers.
- Die IT sieht es in ihren eigenen Werkzeugen nicht. Benutzer erstellen PATs auf unserem Identity Server, außerhalb des Entra-Tenants des Kunden, und nichts hält fest, in welchen KI-Assistenten ein Token kopiert wurde.
- Die IT kann es nicht steuern. Die Anmelderichtlinien des Unternehmens (Multi-Faktor-Authentifizierung, Conditional Access, konforme Geräte) greifen nicht bei einem Token, das die Anmeldung umgeht.
- Die Frage „welcher KI-Client“ stellt sich gar nicht. Ein Token funktioniert in jedem Client, der es mitschicken kann. Das Unternehmen kann Claude Code nicht erlauben und einen anderen, nicht geprüften Assistenten ablehnen.
Die meisten unserer Kunden setzen bereits Microsoft Entra ID ein, und ihre IT verwaltet dort alle anderen Anwendungen. Der MCP-Server sollte keine Ausnahme sein.
Warum nicht unser eigener Identity Server?
Unser Identity Server spricht bereits OAuth, stellt die Tokens aus, die unsere API akzeptiert, und kann die Anmeldung an den Entra-Tenant eines Kunden föderieren. Ihn zum Authorization Server des MCP-Servers zu machen, sah nach dem kürzeren Weg aus. Er scheitert an der Client-Registrierung.
Jeder KI-Client braucht eine Registrierung, und viele davon sind kundenspezifisch. Ein MCP-Client kann sich nur bei einem Authorization Server anmelden, der seine Client-ID und seine Redirect-URI kennt. Die sind oft nicht pro Produkt fix:
- ChatGPT erzeugt für jede Custom App, die ein Workspace anlegt, eine neue Callback-URL und braucht ein Client Secret.
- Copilot Studio erzeugt laut seiner Dokumentation eine für jedes Tool.
- Codex leitet seine Callback-URL aus der vollständigen Server-URL ab.
Mit unserem Identity Server als Authorization Server hätte jeder neue Kunde, jeder Assistent und jede Server-URL einen Client bedeutet, den wir auf unserer Seite anlegen und pflegen, über eine Support-Anfrage. Bei einem Produkt mit vielen Tenants konnten wir das weder betreiben, noch war es zumutbar, Kunden darauf warten zu lassen.
Und jeder Client hätte Geld gekostet. Die Lizenz unseres Identity Servers hängt an der Zahl der OAuth-Clients. Ein Client pro Kunde und KI-Assistent hätte jeden neuen MCP-Kunden zu Lizenzkosten für uns gemacht. Damit wäre der MCP-Server für unsere kleineren Kunden nicht in Frage gekommen, und wir wollten ihn allen anbieten.
Die Selbstbedienungs-Optionen des Protokolls lösen das nicht.
- Mit Dynamic Client Registration (DCR) registriert sich jeder Client selbst. Die aktuelle MCP-Autorisierungsspezifikation (Revision 2026-07-28) erklärt sie für veraltet, zugunsten von Client ID Metadata Documents. Unser Identity Server bietet sie auch nicht an.
- Mit Client ID Metadata Documents (CIMD) weist sich der Client über eine URL aus, die auf seine eigenen Metadaten zeigt. Das erspart die Registrierung. Es heißt aber auch: Jeder Client, der ein solches Dokument veröffentlicht, kann sich verbinden, und eine Allow-List läge bei uns, nicht beim Kunden.
Und die Kontrolle läge am falschen Ort. Die Client-Registrierungen lägen in unserem System, nicht im Tenant des Kunden. Die Entra ID des Kunden sähe immer nur time cockpit bei der Anmeldung, nie, welcher KI-Assistent dahintersteckt.
Mit der Entra ID des Kunden als Authorization Server wandert die Registrierung dorthin, wo sie hingehört. Es bleibt eine Vorab-Registrierung, denn Microsoft Entra ID unterstützt weder DCR noch CIMD. Microsoft schreibt das für DCR und im eigenen Entwicklerblog für beides, und Entras Metadaten kündigen keines davon an. Aber die Registrierung macht der Administrator des Kunden, in seinem eigenen Tenant, ohne auf uns zu warten. Unser Identity Server behält die Aufgabe, die er gut kann: zu entscheiden, wer dieser Benutzer in time cockpit ist.
Das Zielbild: zwei Autoritäten
Wir teilen die Aufgabe zwischen zwei Systemen auf, die jeweils schon einen Teil davon verantworten.
- Die Entra ID des Kunden entscheidet über den Zugang: wer sich anmelden darf, über welchen KI-Client, unter welchen Richtlinien.
- Unser eigener Identity Server bleibt die Autorität für das Produkt: welcher time-cockpit-Tenant und welcher Benutzer diese Person ist, und damit, was sie sehen und tun darf.
Ein Tool-Aufruf läuft in vier Schritten:
- Der KI-Client meldet den Benutzer am Entra-Tenant des Kunden an und erhält ein Access Token für unseren MCP-Server. Der Benutzer meldet sich mit seinem Firmenkonto an; niemand kopiert persönliche Zugangsdaten.
- Der Client ruft den MCP-Server mit diesem Token auf.
- Der MCP-Server prüft das Token. Dann tauscht er es bei unserem Identity Server gegen ein time-cockpit-Token für denselben Benutzer, mit dem standardisierten Token-Exchange-Grant (RFC 8693). Unser Identity Server ordnet den Entra-Benutzer einem time-cockpit-Tenant und -Benutzer zu. Diese Zuordnung gab es schon: Kunden konnten sich bereits vorher mit Entra ID an time cockpit selbst anmelden.
- Der MCP-Server ruft die Produkt-API mit dem time-cockpit-Token auf. Ab da gelten dieselben Berechtigungen wie im Web-Client.
Das Entra-Token erreicht die Produkt-API nie. Das ist nicht nur aufgeräumt: Die MCP-Autorisierungsspezifikation verbietet einem MCP-Server, das Token des Clients an nachgelagerte Dienste durchzureichen. Durch den Austausch erhält das Produkt ein Token, das es selbst ausgestellt hat, für genau einen Benutzer und Tenant.
Der Austausch ist ein einfacher Form-Post an den Token-Endpunkt, den unser Identity Server in seinem Discovery-Dokument veröffentlicht:
POST <token_endpoint>
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=<validated Entra access token>
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&requested_token_type=urn:ietf:params:oauth:token-type:access_token
&client_id=<MCP server>&client_secret=<...>Der MCP-Server cacht das Ergebnis pro Benutzer, Tenant und Umgebung, und nie länger, als das Entra-Token gültig ist. Ein Benutzer, den die IT in Entra sperrt, verliert den Zugang zum MCP-Server daher spätestens, wenn sein letztes Entra-Token abläuft.
Was die IT des Kunden steuert
Danach fragen Unternehmenskunden, deshalb haben wir es so gebaut, dass es vollständig in ihrem eigenen Tenant liegt.
Welche KI-Clients sich verbinden dürfen. Wir betreiben den MCP-Server als mandantenfähige Ressourcen-Anwendung in Entra mit einer delegierten Berechtigung, mcp.access. Der Administrator des Kunden legt die Client-Anwendungen in seinem eigenen Tenant an und erteilt die Zustimmung für diese Berechtigung. Er kann eine Registrierung für alle KI-Assistenten verwenden oder eine pro Assistent, zum Beispiel eine für Claude Code und Codex, eine für die Claude-App und eine für ChatGPT. Mit getrennten Registrierungen kann die IT einen einzelnen Assistenten einschränken oder sperren, ohne die anderen anzufassen. Entra stellt Tokens für unsere API nur Client-Anwendungen aus, denen die Berechtigung erteilt wurde. Ob Benutzer sie selbst erteilen dürfen oder nur ein Administrator, regelt die Consent-Richtlinie des Tenants.
Wer sich anmelden darf. Die Client-Registrierungen sind gewöhnliche Entra-Anwendungen, deshalb stehen dafür die Standard-Steuerungen von Entra zur Verfügung. Die IT kann eine Benutzerzuweisung verlangen und den Zugang auf ausgewählte Gruppen beschränken. Conditional-Access-Richtlinien und Multi-Faktor-Authentifizierung gelten für die Anmeldung wie bei jeder anderen App. Wir dokumentieren diese Optionen für unsere Kunden, haben aber noch nicht jede Kombination durchgängig gegen unseren Server geprüft.
Wie es eingerichtet wird. Der einmalige Aufwand für den Administrator ist eine Registrierung pro Client, und unsere API muss in seinem Tenant bekannt gemacht werden. Unsere Setup-Dokumentation (Englisch) beschreibt die Schritte im Portal, ein Bicep-Template, das die Registrierung samt Berechtigung und optional mit tenantweiter Zustimmung anlegt, sowie die Redirect-URI für jeden KI-Client.
Was der Benutzer einschränken kann und was nur wir ändern können
Innerhalb dessen, was die IT erlaubt, entscheidet der Benutzer, wie viel ein Assistent auf einer Verbindung darf. Zwei Einstellungen sind Teil der Verbindung selbst:
readonlyblendet jedes Tool aus, das Daten ändert, und lehnt seinen Aufruf ab.owndatabeschränkt die Verbindung auf die eigenen Daten des Benutzers, zum Beispiel seine eigenen Zeitbuchungen.
Beide können nur einschränken, was eine Verbindung darf. Genau deshalb darf der Client sie überhaupt setzen.
Eine Einstellung wirkt in die andere Richtung. Standardmäßig braucht jedes generische Anlegen, Ändern und Löschen eine ausdrückliche Bestätigung: Der Server antwortet zuerst mit einer Beschreibung der Änderung, und der Assistent muss den Aufruf mit confirmed=true wiederholen, nachdem der Benutzer zugestimmt hat. Das abzuschalten würde erweitern, was eine Anfrage darf, deshalb ist es keine Client-Einstellung. Nur der Betreiber des Servers kann sie ändern, und eine Anfrage, die sie setzen will, wird abgelehnt.
Unter all dem gelten immer die Berechtigungen des Produkts selbst. Ein Assistent erreicht keinen Datensatz, den der Benutzer im Web-Client nicht öffnen kann, und er kommt auch nicht durch Raten eines technischen Namens dorthin. Jeder Tool-Aufruf wird mit Tenant, Benutzer, Tool und Ergebnis protokolliert, aber ohne Argumente oder Ergebnisdaten.
Die Kompromisse
- Ein einmaliges Setup beim Kunden. Weil Entra weder DCR noch CIMD unterstützt, braucht jeder KI-Client die Client-ID einer Registrierung im Tenant des Kunden, und jede Client-Konfiguration braucht diese ID. Für ein Unternehmen ist das genauso Funktion wie Aufwand: Es ist der Schritt, an dem die IT entscheidet, welche Assistenten erlaubt sind.
- Entra und MCP passen nicht von Haus aus zusammen. Entra veröffentlicht nicht die Metadaten, die MCP-Clients suchen, und lehnt Parameter ab, die sie mitschicken. Den MCP-Server zu seinem eigenen OAuth-Eingang zu machen, mit Metadaten und einem schlanken Proxy zu Entra, hat einen guten Teil der Zeit gekostet.
- Vorerst nur Entra. Ein Kunde mit einem anderen Identity Provider kann den Remote-MCP-Server heute nicht nutzen.
- Ein Schritt mehr. Die Anmeldung läuft über die Metadaten des MCP-Servers zu Entra, und der erste Aufruf pro Benutzer und Verbindung kostet einen Token-Austausch. Danach wird das gecachte Token wiederverwendet.
- Der Server kann nicht steuern, wohin die Daten gehen. Was ein Assistent über den MCP-Server liest, geht an den KI-Anbieter und wird nach dessen Bedingungen verarbeitet. Berechtigungen,
readonlyundowndatabegrenzen, was ein Benutzer sehen kann, nicht, wohin es danach geht. Diese Entscheidung bleibt bei der IT und dem Datenschutzbeauftragten des Kunden, und das sagen wir in unserer Dokumentation auch so.
Wann Access Tokens weiterhin passen
Für ein Skript, einen geplanten Import oder eine Service-Integration, die ohne Benutzer davor läuft, bleibt ein PAT für die Web API das richtige Werkzeug. Dafür verwenden wir sie. Die Argumentation oben betrifft eine andere Situation: Eine Person verbindet einen allgemeinen KI-Assistenten mit Unternehmensdaten. Dort sollte der Identity Provider des Unternehmens entscheiden, nicht ein Token in jemandes Zwischenablage.
Wo wir das einsetzen
So funktioniert der Remote-MCP-Server von time cockpit. Er ist als Public Preview unter https://mcp.timecockpit.com verfügbar. Kunden verbinden Claude Code, die Claude-App, Codex, VS Code und ChatGPT damit; diese Clients sind getestet. Jeder Benutzer meldet sich mit einem Konto aus dem Entra-Tenant seines Unternehmens an, und der Identity Server des Produkts ordnet ihn seinem time-cockpit-Tenant zu.
Fazit
- Ein Personal Access Token beantwortet „wer ruft an“, aber nicht die Fragen, die die IT im Unternehmen stellt: welcher Assistent, unter welcher Richtlinie und wie man ihn abschaltet.
- Lassen Sie den Identity Provider des Kunden über den Zugang entscheiden, und behalten Sie Ihren eigenen Identity Server als Autorität für Ihr Produkt. Token Exchange verbindet beides, ohne das Token des Kunden durchzureichen.
- Geben Sie der IT eine App-Registrierung pro KI-Client, und lassen Sie Benutzer eine Verbindung einschränken, aber nie erweitern.
- Behalten Sie Access Tokens für das, wofür sie gut sind: Integrationen ohne Person davor.
Wenn Sie einen MCP-Server vor ein bestehendes Produkt stellen und die IT Ihrer Kunden die Kontrolle darüber haben will: Wir haben das gebaut. Sprechen wir über Ihr Projekt.