Identity Forwarding

Delegierte Authentifizierung zu Third-Party-Systemen mit meinGPT JWT

JWT Identity Forwarding

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.

Token-Details

EigenschaftWert
AlgorithmusRS256 (RSA + SHA-256)
Gültigkeit1 Stunde
HeaderEnthält kid (Key-ID) für Key-Rotation
IssuerDie Origin Deiner meinGPT-Instanz (z. B. https://app.meingpt.com)

Claims-Referenz

ClaimTypBeschreibung
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" }
  ]
}

Verifikation über JWKS

Öffentliche Schlüssel werden pro Organisation bereitgestellt:

https://app.meingpt.com/api/custom-apps/v1/jwks/{organizationId}
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;
}

Transport: Custom MCP Server

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.

So aktivierst Du es

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.

JWT-Authentifizierung aktivieren

Schalte JWT Authentication ein. Der Hinweistext bestätigt: „Sends a signed meinGPT JWT in header X-meinGPT-JWT."

Token auf Deinem Server lesen

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' });
  }
});

Custom-Header mit JWT-Platzhalter

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.

Transport: Custom AI Apps (iframe)

Für eingebettete AI Apps wird der Token beim initialen Laden im URL-Hash-Fragment übergeben und per postMessage erneuert.

Initialer Token

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');
}

Token-Refresh per postMessage

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:

NachrichtRichtungFelderBeschreibung
MEINGPT_TOKEN_REFRESHApp → meinGPTNeuen Token anfragen
MEINGPT_TOKEN_RESPONSEmeinGPT → Apptoken, expiresAtNeuer signierter JWT + Ablaufzeitpunkt
MEINGPT_TOKEN_ERRORmeinGPT → ApperrorFehlermeldung als String

Hinweis

meinGPT validiert die postMessage-Origin gegen Deine konfigurierte Embed-URL. Nachrichten von unbekannten Origins werden ignoriert.

Vollständiges Lifecycle-Beispiel

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);
  }
});

Sicherheitshinweise

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

Weiterführend

War diese Seite hilfreich?