Auth Provider Integration
When a user launches your application through the General Wisdom marketplace, your app receives a signed JWT containing session claims. Your backend must exchange this JWT for credentials in your own identity provider so the user gets a seamless, authenticated experience within your application.
How JWT Exchange Works
sequenceDiagram
participant Marketplace as General Wisdom Marketplace
participant SDK as Provider SDK (your frontend)
participant Backend as Your Backend
participant IdP as Your Identity Provider
Marketplace->>SDK: Launch with ?gwSession=<JWT>
SDK->>SDK: Validate JWT signature (JWKS)
SDK->>Backend: POST /auth/exchange (Bearer JWT)
Backend->>Backend: Verify JWT claims (iss, applicationId, exp)
Backend->>IdP: Find or create user
IdP-->>Backend: User record
Backend->>IdP: Authenticate user (ROPC grant)
IdP-->>Backend: Access token + refresh token
Backend-->>SDK: Tokens + user info
SDK->>SDK: Store tokens, start session timer
JWT Claims Reference
Every marketplace JWT contains these claims:
| Claim | Type | Description |
|---|---|---|
userId | string | Unique General Wisdom user identifier |
orgId | string | Organization the user belongs to |
applicationId | string | Your registered application ID |
sessionId | string | Unique session identifier |
email | string | User email address (when available) |
exp | number | Token expiration (Unix timestamp) |
iss | string | Issuer (generalwisdom.com) |
durationMinutes | number | Session duration in minutes |
Provider Selection Guide
Choose your identity provider based on your existing infrastructure:
| Provider | Best For | User Management | Token Format |
|---|---|---|---|
| Keycloak | Self-hosted, full control, open source | Admin REST API | JWT (realm_access roles) |
| Auth0 | Managed service, rapid setup | Management API v2 | JWT (namespaced claims) |
| Okta | Enterprise SSO, workforce identity | Users API + SSWS tokens | JWT (groups claim) |
| Microsoft Entra ID | Azure ecosystem, Microsoft 365 | Microsoft Graph API | JWT (app roles) |
| AWS Cognito | AWS-native, cost-effective | Admin APIs (SigV4) | JWT (cognito:groups) |
Common Exchange Pattern
Regardless of which provider you use, the backend exchange follows a consistent pattern:
async function exchangeMarketplaceToken(marketplaceJwt: string) {
// 1. Validate the marketplace JWT
const claims = await validateJWT(marketplaceJwt, {
issuer: 'generalwisdom.com',
jwksUri: 'https://api.generalwisdom.com/.well-known/jwks.json',
algorithms: ['RS256'],
});
// 2. Verify applicationId binding
if (claims.applicationId !== process.env.APPLICATION_ID) {
throw new Error('Token issued for different application');
}
// 3. Find or create user in your IdP
let user = await idp.findUser(claims.userId);
if (!user) {
user = await idp.createUser({
username: `gw-${claims.userId}`,
email: claims.email,
attributes: { gwUserId: claims.userId, orgId: claims.orgId },
});
}
// 4. Obtain tokens from your IdP
const tokens = await idp.authenticateUser(user);
return {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in,
};
}
Security Requirements
All provider integrations must follow these security requirements:
- Always validate the JWT signature using the JWKS endpoint before trusting any claims
- Verify the
applicationIdclaim matches your registered application - Check token expiration before processing the exchange
- Use confidential clients with client secrets for all backend token exchanges
- Never expose admin API credentials (API tokens, client secrets) to the frontend
- Generate deterministic passwords derived from
userId + clientSecretusing SHA-256 -- never store raw passwords - Use HTTPS for all identity provider communication
SDK Integration
The Provider SDK handles the frontend portion of the exchange automatically via lifecycle hooks:
import MarketplaceSDK from '@mission_sciences/provider-sdk';
const sdk = new MarketplaceSDK({
apiKey: 'gwsk_...',
applicationId: 'your-app-id',
jwksUri: 'https://api.generalwisdom.com/.well-known/jwks.json',
hooks: {
onSessionStart: async (context) => {
// Exchange JWT for your IdP tokens
const tokens = await fetch('/auth/exchange', {
method: 'POST',
headers: { Authorization: `Bearer ${context.jwt}` },
}).then(r => r.json());
// Store tokens for your application
sessionStorage.setItem('access_token', tokens.accessToken);
},
onSessionEnd: async (context) => {
// Clean up tokens and revoke sessions
sessionStorage.clear();
await fetch('/auth/logout', { method: 'POST' });
},
},
});
await sdk.initialize();
Next Steps
Choose your provider guide to get started with a complete integration:
- Keycloak -- Open source, self-hosted identity management
- Auth0 -- Managed identity platform by Okta
- Okta -- Enterprise workforce identity
- Microsoft Entra ID -- Azure Active Directory
- AWS Cognito -- AWS-native user pools