Mit JWT Identity Forwarding gibt meinGPT einen signierten JSON Web Token an Dritt-Systeme weiter, damit diese den aktuellen Nutzer und die Organisation sicher identifizieren können.
Dieses Muster wird in zwei Bereichen genutzt:
Custom MCP Server — Token im HTTP-Header X-meinGPT-JWT
Custom AI Apps (iframe) — Token im URL-Hash-Fragment
Achtung
JWT-Tokens werden nur für Nutzer mit der Rolle Admin oder Mitglied ausgestellt. Viewer erhalten keine Tokens.
Eigenschaft Wert Algorithmus RS256 (RSA + SHA-256) Gültigkeit 1 Stunde Header Enthält kid (Key-ID) für Key-Rotation Issuer Die Origin Deiner meinGPT-Instanz (z. B. https://app.meingpt.com)
Claim Typ Beschreibung issstringIssuer — die Plattform-Origin (z. B. https://app.meingpt.com) substringSubject — die User-ID audstringAudience — die Organization-ID expnumberAblaufzeit (Unix-Timestamp, 1 Stunde ab Ausstellung) iatnumberAusstellungszeitpunkt (Unix-Timestamp) jtistringEindeutige Token-ID (UUID, ändert sich bei jeder Ausstellung) emailstringE-Mail-Adresse des Nutzers usernamestringAnzeigename des Nutzers organizationNamestringName der Organisation rolestring"admin" oder "member"teamsarrayTeams des Nutzers — jeder Eintrag hat id und name
Beispiel-Payload:
{
"iss" : "https://app.meingpt.com" ,
"sub" : "clx1234567890" ,
"aud" : "clx0987654321" ,
"exp" : 1719504000 ,
"iat" : 1719500400 ,
"jti" : "a1b2c3d4-e5f6-7890-abcd-ef1234567890" ,
"email" : "max@example.com" ,
"username" : "Max Mustermann" ,
"organizationName" : "Acme Corp" ,
"role" : "admin" ,
"teams" : [
{ "id" : "clxteam001" , "name" : "Engineering" }
]
}
Öffentliche Schlüssel werden pro Organisation bereitgestellt:
https://app.meingpt.com/api/custom-apps/v1/jwks/{organizationId}
Node.js (jose) Python (PyJWT)
import { createRemoteJWKSet, jwtVerify } from 'jose' ;
const JWKS = createRemoteJWKSet (
new URL ( 'https://app.meingpt.com/api/custom-apps/v1/jwks/<organizationId>' )
);
async function verifyMeinGptJwt ( token : string ) {
const { payload } = await jwtVerify (token, JWKS , {
issuer: 'https://app.meingpt.com' ,
audience: '<organizationId>' ,
});
console. log ( 'User:' , payload.email);
console. log ( 'Role:' , payload.role);
return payload;
}
+
Wenn JWT Identity Forwarding für einen MCP-Server aktiviert ist, enthält jeder Request:
X-meinGPT-JWT : eyJhbGciOiJSUzI1NiIs...
Tokens werden innerhalb einer Chat-Session gecacht und 30 Sekunden vor Ablauf automatisch erneuert. Dein Server muss keine neuen Tokens anfragen — jeder MCP-Call kommt mit einem gültigen Token an.
Assistenten-Einstellungen öffnen
Navigiere zur Konfiguration Deines Assistenten und öffne den Bereich Tools .
Custom MCP Server hinzufügen oder bearbeiten
Füge einen neuen Custom MCP Server hinzu oder bearbeite einen bestehenden.
Signierte Nutzeridentität aktivieren
Schalte Signierte Nutzeridentität ein. Der Hinweistext bestätigt: „Sendet einen signierten meinGPT-JWT im Header X-meinGPT-JWT."
Extrahiere den Header und verifiziere ihn:
// Express-Middleware-Beispiel
import { createRemoteJWKSet, jwtVerify } from 'jose' ;
const JWKS = createRemoteJWKSet (
new URL ( 'https://app.meingpt.com/api/custom-apps/v1/jwks/<organizationId>' )
);
app. use ( async ( req , res , next ) => {
const token = req.headers[ 'x-meingpt-jwt' ];
if ( ! token) return res. status ( 401 ). json ({ error: 'Missing JWT' });
try {
const { payload } = await jwtVerify (token, JWKS , {
issuer: 'https://app.meingpt.com' ,
audience: '<organizationId>' ,
});
req.user = payload;
next ();
} catch {
res. status ( 401 ). json ({ error: 'Invalid token' });
}
});
Alternativ zum Schalter kannst Du den Platzhalter {{MEINGPT_JWT}} in jedem Custom-Header-Wert verwenden. Das ist nützlich, wenn Dein Server den Token in einem anderen Header erwartet (z. B. Authorization: Bearer {{MEINGPT_JWT}}). Der Platzhalter wird zur Laufzeit durch den signierten JWT ersetzt.
+
Für eingebettete AI Apps wird der Token beim initialen Laden im URL-Hash-Fragment übergeben und per postMessage erneuert.
Wenn meinGPT Deine App im iframe lädt, sieht die URL so aus:
https://deine-app.example.com/path#token=eyJhbGciOiJSUzI1NiIs...
So extrahierst Du ihn im Frontend:
function getInitialToken () {
const params = new URLSearchParams (window.location.hash. slice ( 1 ));
return params. get ( 'token' );
}
Tokens laufen nach 1 Stunde ab. Deine App kann jederzeit per postMessage einen neuen Token anfragen:
1. Neuen Token anfragen — sende an das Parent-Fenster:
window.parent. postMessage ({ type: 'MEINGPT_TOKEN_REFRESH' }, '*' );
2. Auf die Antwort lauschen:
window. addEventListener ( 'message' , ( event ) => {
// Origin validieren
if (event.origin !== 'https://app.meingpt.com' ) return ;
if (event.data.type === 'MEINGPT_TOKEN_RESPONSE' ) {
// Erfolg — neuen Token speichern
const { token , expiresAt } = event.data;
setToken (token);
scheduleRefresh ( new Date (expiresAt));
}
if (event.data.type === 'MEINGPT_TOKEN_ERROR' ) {
// Token-Refresh fehlgeschlagen
console. error ( 'Token refresh failed:' , event.data.error);
}
});
Nachrichtentypen:
Nachricht Richtung Felder Beschreibung MEINGPT_TOKEN_REFRESHApp → meinGPT — Neuen Token anfragen MEINGPT_TOKEN_RESPONSEmeinGPT → App token, expiresAtNeuer signierter JWT + Ablaufzeitpunkt MEINGPT_TOKEN_ERRORmeinGPT → App errorFehlermeldung als String
Hinweis
meinGPT validiert die postMessage-Origin gegen Deine konfigurierte Embed-URL. Nachrichten von unbekannten Origins werden ignoriert.
let currentToken = null ;
let refreshTimer = null ;
// 1. Initialen Token aus dem URL-Hash lesen
currentToken = new URLSearchParams (window.location.hash. slice ( 1 )). get ( 'token' );
// 2. Refresh planen (z. B. 5 Minuten vor Ablauf)
function scheduleRefresh ( expiresAt ) {
clearTimeout (refreshTimer);
const ms = new Date (expiresAt). getTime () - Date. now () - 5 * 60 * 1000 ;
if (ms > 0 ) {
refreshTimer = setTimeout (requestRefresh, ms);
}
}
// 3. Refresh per postMessage anfragen
function requestRefresh () {
window.parent. postMessage ({ type: 'MEINGPT_TOKEN_REFRESH' }, '*' );
}
// 4. Antwort verarbeiten
window. addEventListener ( 'message' , ( event ) => {
if (event.origin !== 'https://app.meingpt.com' ) return ;
if (event.data.type === 'MEINGPT_TOKEN_RESPONSE' ) {
currentToken = event.data.token;
scheduleRefresh (event.data.expiresAt);
}
});
+
Achtung
Verifiziere immer die JWT-Signatur über den JWKS-Endpunkt. Vertraue dem Token-Payload niemals ohne kryptografische Prüfung.
Signatur verifizieren — nutze den JWKS-Endpunkt, dekodiere nicht einfach nur den Payload
exp prüfen — lehne abgelaufene Tokens ab
aud validieren — stelle sicher, dass die Audience mit Deiner erwarteten Organization-ID übereinstimmt
HTTPS verwenden — Dein Endpunkt muss TLS nutzen, um den Token bei der Übertragung zu schützen
Tokens nicht loggen — JWTs enthalten personenbezogene Daten (E-Mail, Name); vermeide es, sie in Anwendungslogs zu schreiben
iframe-Apps: event.origin validieren — akzeptiere postMessage-Events nur von der Origin Deiner meinGPT-Instanz