OAuth 2.0
Externe Anwendungen ueber OAuth 2.0 mit PKCE mit Spedy verbinden -- fuer KI-Tools, IDE-Erweiterungen und eigene Integrationen.
Spedy enthaelt einen vollstaendigen OAuth-2.0-Autorisierungsserver fuer die Anbindung externer Anwendungen. Dies ist der primaere Weg, wie KI-Tools wie Claude Desktop, Cursor und andere MCP-faehige Clients sich bei Spedy authentifizieren.
Der OAuth-Server implementiert RFC 6749 (Authorization Code Flow), RFC 7636 (PKCE), RFC 7591 (Dynamic Client Registration), RFC 8414 (Server Metadata) und RFC 9728 (Protected Resource Metadata).
Discovery
OAuth-Clients koennen die Endpunkte von Spedy automatisch ueber Standard-Metadaten-Endpunkte erkennen:
GET /.well-known/oauth-authorization-server
GET /.well-known/oauth-protected-resourceDiese oeffentlichen Endpunkte geben die Faehigkeiten des Autorisierungsservers, unterstuetzte Grant-Typen und Endpunkt-URLs zurueck. Sie respektieren Multi-Tenant-Subdomains -- die Metadaten-URLs sind auf die anfragende Organisation beschraenkt.
Dynamic Client Registration
Externe Anwendungen registrieren sich ueber RFC 7591 Dynamic Client Registration. Dieser Endpunkt erfordert Authentifizierung -- Clients muessen ein gueltiges JWT praesentieren.
POST /api/v1/oauth/registerRequest Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| client_name | string | Ja | Anzeigename der Anwendung |
| redirect_uris | string[] | Ja | Erlaubte Redirect-URIs (muessen HTTPS sein, ausser Loopback) |
| client_uri | string | Nein | Homepage-URL der Anwendung |
| logo_uri | string | Nein | Logo-URL fuer den Consent-Bildschirm |
Beispiel-Request
{
"client_name": "Meine IDE-Erweiterung",
"redirect_uris": ["https://meine-erweiterung.example.com/callback"]
}Beispiel-Response
{
"client_id": "abc123def456...",
"client_secret": "spd_...",
"client_name": "Meine IDE-Erweiterung",
"redirect_uris": ["https://meine-erweiterung.example.com/callback"],
"token_endpoint_auth_method": "client_secret_post",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}Das client_secret wird nur einmalig bei der Registrierung zurueckgegeben. Speichere es sicher. Ueber DCR registrierte Clients sind vertrauliche Clients und muessen das client_secret beim Token-Austausch angeben.
Rate-Limit: 5 Registrierungen pro Stunde pro IP.
Autorisierungsablauf
Spedy nutzt den Authorization Code Flow mit PKCE (S256). Plain-Code-Challenges werden nicht unterstuetzt.
1. Nutzer zur Autorisierung weiterleiten
GET /api/v1/oauth/authorize| Parameter | Pflicht | Beschreibung |
|---|---|---|
| response_type | Ja | Muss code sein |
| client_id | Ja | Deine Client-ID |
| redirect_uri | Ja | Muss mit einer registrierten Redirect-URI uebereinstimmen |
| state | Ja | CSRF-Token (mindestens 32 Zeichen) |
| code_challenge | Ja | PKCE-S256-Challenge |
| code_challenge_method | Nein | Muss S256 sein (Standard) |
| scope | Nein | Leerzeichen-getrennte Scopes (Standard: read write) |
| resource | Nein | Resource-Indicator (RFC 8707) |
Der Nutzer wird zur Consent-Seite von Spedy weitergeleitet. Bei aktiver Session kann er ohne erneute Anmeldung zustimmen.
2. Autorisierungscode eintauschen
POST /api/v1/oauth/token| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| grant_type | string | Ja | authorization_code |
| code | string | Ja | Der Autorisierungscode aus dem Callback |
| redirect_uri | string | Ja | Muss mit der urspruenglichen Anfrage uebereinstimmen |
| client_id | string | Ja | Deine Client-ID |
| client_secret | string | Bedingt | Erforderlich fuer vertrauliche Clients |
| code_verifier | string | Ja | PKCE-Code-Verifier |
Beispiel-Response
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "eyJ...",
"scope": "read write"
}3. Access-Token erneuern
POST /api/v1/oauth/token| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| grant_type | string | Ja | refresh_token |
| refresh_token | string | Ja | Das Refresh-Token |
| client_id | string | Ja | Deine Client-ID |
| organization_id | string | Nein | Zu einer anderen Organisation wechseln |
Wenn organization_id angegeben wird, ist das neue Access-Token auf diese Organisation beschraenkt. Der Nutzer muss eine aktive Mitgliedschaft in der Zielorganisation haben, und der Client muss dafuer autorisiert sein.
Token-Widerruf
POST /api/v1/oauth/revoke| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| token | string | Ja | Das zu widerrufende Access-Token |
Gemaess RFC 7009 gibt dieser Endpunkt immer 200 OK zurueck, auch bei ungueltigen Tokens.
OAuth-Tokens werden auch automatisch widerrufen, wenn ein Nutzer sich abmeldet oder sein Passwort zuruecksetzt.
Organisationswechsel
Nutzer, die mehreren Organisationen angehoeren, koennen den Kontext ohne erneute Authentifizierung wechseln:
GET /api/v1/oauth/me/organizations?client_id={client_id}Gibt die Liste der Organisationen zurueck, denen der Nutzer angehoert und die den angegebenen Client autorisiert haben. Verwende den Parameter organization_id in der Refresh-Token-Anfrage zum Wechseln.
Scopes
| Scope | Beschreibung |
|---|---|
read | Lesezugriff auf Boards, Tickets, Wiki und andere Ressourcen |
write | Ressourcen erstellen und bearbeiten |
admin | Administrative Operationen |
Standard-Scopes sind read write, wenn keine angefordert werden.
Sicherheit
- PKCE erforderlich -- nur S256 wird unterstuetzt, Plain wird abgelehnt
- Client Secrets -- vertrauliche Clients verwenden SHA256-gehashte Secrets mit timing-sicherem Vergleich
- State-Parameter -- mindestens 32 Zeichen erforderlich fuer CSRF-Schutz
- Redirect-URI-Validierung -- nur vorregistrierte URIs werden akzeptiert; HTTPS erforderlich (ausser Loopback)
- Token-Widerruf -- Tokens werden bei Abmeldung und Passwortzuruecksetzung widerrufen. Sowohl Access-Tokens als auch Refresh-Tokens werden serverseitig fuer zustandsbehafteten Widerruf gespeichert, sodass widerrufene Tokens nicht wiederverwendet werden koennen, selbst wenn die JWT-Signatur noch gueltig ist
- Rate-Limiting -- alle OAuth-Endpunkte sind pro IP rate-limitiert