Authentifizierung
API und MCP-Server sind beide OAuth Resource Server. Ein Client meldet sich über den Glasswise-Login an, holt ein Access Token vom Authorization Server und schickt es als Bearer-Token mit.
Authorization Server
Abschnitt betitelt „Authorization Server“Der Glasswise Authorization Server ist derselbe Dienst, über den sich Winzer:innen in der Glasswise-App anmelden.
- Issuer:
https://auth.glasswise.eu/v1 - Flow: Authorization Code mit PKCE
- Client-Registrierung: Client ID Metadata Documents (CIMD). Die Client-ID ist eine HTTPS-URL, die die Metadaten des Clients hostet; der Authorization Server lädt und prüft sie.
Der MCP-Server veröffentlicht seinen Authorization Server in den Protected-Resource-Metadaten unter https://mcp.glasswise.eu/.well-known/oauth-protected-resource, einschließlich der pfadbezogenen URL https://mcp.glasswise.eu/.well-known/oauth-protected-resource/mcp.
Erforderlicher Scope
Abschnitt betitelt „Erforderlicher Scope“openid graphql:role:api_userDer Role-Scope beschränkt das Token auf die Rolle api_user. Beide Server lehnen ein Token ab, dessen Role-Claims nicht genau diese eine Rolle sind, auch ein Token, das ohne Role-Scope ausgestellt wurde. Fordere den einfachen graphql-Scope nicht zusammen mit einem Role-Scope an; der Authorization Server lehnt die Kombination ab. Fordere openid graphql:role:api_user an.
- Access Tokens sind JWTs, mit RS256 signiert, und laufen nach 15 Minuten ab.
- Das Token trägt die User-ID der aufrufenden Person. Die API reicht es unverändert upstream weiter, sodass die Row-Level-Berechtigungen genau das sehen, was diese Person sehen darf.
- Die Audience des Tokens ist die OAuth-Client-ID, nicht die API oder der MCP-Server. Der Role-Scope und die Role-Claims sind die Grenze.
Wie ein 401 aussieht
Abschnitt betitelt „Wie ein 401 aussieht“Die API beantwortet ein fehlendes Token mit einer einfachen Challenge und ein vorgelegtes, aber abgelehntes Token mit error="invalid_token":
WWW-Authenticate: BearerWWW-Authenticate: Bearer error="invalid_token"Beide Antworten kommen mit einem application/problem+json-Body:
{ "type": "about:blank", "title": "Unauthorized", "status": 401, "detail": "a valid bearer token is required"}Die Challenge des MCP-Servers trägt zusätzlich die URL der Protected-Resource-Metadaten und den erforderlichen Scope:
WWW-Authenticate: Bearer resource_metadata="https://mcp.glasswise.eu/.well-known/oauth-protected-resource", scope="openid graphql:role:api_user"