Skip to main content
Glama
FIX_IMPLEMENTATION_SUMMARY.md6.65 kB
# Fix Implementation Summary: Cognito User Detection Issue ## Date: 2025-11-10 ## Problem Statement Cognito legacy users (like `david+saola@umbrellacost.com`) were being incorrectly detected as Keycloak UM 2.0 users, causing: - Wrong API key format (empty divisionId instead of numeric) - 500 errors on API requests - Authentication failures ### Root Cause The code in `dual-auth.ts:479-492` was re-detecting the user management system on every OAuth API request by calling the unreliable `/v1/user-management/users/user-realm` API endpoint, which returns realm data for users still on Cognito. This ignored which authentication method actually succeeded during login. ## Solution Implemented (Option B) **Store the actual authentication method in the OAuth JWT token** instead of re-detecting it on every request. ## Files Modified ### 1. `/src/types.ts` **Change**: Added `userManagementInfo` field to `AuthToken` interface ```typescript import type { UserManagementInfo } from './dual-auth.js'; export interface AuthToken { Authorization: string; apikey?: string; userManagementInfo?: UserManagementInfo; // NEW: Actual auth method that succeeded } ``` ### 2. `/src/auth/token-manager.ts` **Change**: Store and retrieve `userManagementInfo` in JWT tokens ```typescript // In createToken() - lines 124-131 const token = await new SignJWT({ sub: userEmail, clientId, umbrellaAuth: { Authorization: umbrellaAuth.Authorization, userManagementInfo: umbrellaAuth.userManagementInfo // NEW: Store in token } }) // In verifyToken() - lines 166-170 const umbrellaAuth: AuthToken = { Authorization: tokenPayload.umbrellaAuth.Authorization, userManagementInfo: tokenPayload.umbrellaAuth.userManagementInfo // NEW: Extract from token }; ``` ### 3. `/src/dual-auth.ts` **Change 1**: Include `userManagementInfo` in authentication responses (lines 269-272, 300-303) ```typescript // In authenticateKeycloak() return { Authorization: response.data.Authorization, userManagementInfo: this.userManagementInfo || undefined // NEW: Include actual auth method }; // In authenticateCognito() return { Authorization: response.data.jwtToken, userManagementInfo: this.userManagementInfo || undefined // NEW: Include actual auth method }; ``` **Change 2**: Remove unreliable re-detection logic (lines 481-490) **BEFORE** (BROKEN): ```typescript // For OAuth users: ensure userManagementInfo is set before proceeding if (this.token && !this.userManagementInfo) { console.error(`[DUAL-AUTH] ⚠️ OAuth user but userManagementInfo not set! Detecting user management system...`); if (this.username) { this.userManagementInfo = await this.detectUserManagementSystem(this.username); // ❌ UNRELIABLE! console.error(`[DUAL-AUTH] ✅ User management system detected: isKeycloak=${this.userManagementInfo.isKeycloak}`); } else { console.error(`[DUAL-AUTH] ❌ Cannot detect user management system: username not available`); this.userManagementInfo = { isKeycloak: false, authMethod: 'cognito' }; } } ``` **AFTER** (FIXED): ```typescript // For OAuth users: userManagementInfo should already be set from the stored token // DO NOT re-detect - use the auth method that actually succeeded during login if (this.token && !this.userManagementInfo) { console.error(`[DUAL-AUTH] ⚠️ OAuth user but userManagementInfo not set!`); console.error(`[DUAL-AUTH] This should not happen - userManagementInfo should be in the token.`); console.error(`[DUAL-AUTH] Defaulting to Cognito to be safe (most common legacy auth method).`); // DO NOT call detectUserManagementSystem() - it's unreliable for users in migration state // The token should already contain the correct auth method from login this.userManagementInfo = { isKeycloak: false, authMethod: 'cognito' }; } ``` ## How the Fix Works ### Authentication Flow (Initial Login) 1. User attempts login 2. System tries Keycloak auth first → May fail with 500 for Cognito users 3. Falls back to Cognito auth → Succeeds for Cognito users 4. Sets `this.userManagementInfo` based on which method succeeded 5. **NEW**: Stores this info in the JWT token when creating it ### Subsequent API Requests 1. User makes API request with OAuth Bearer token 2. Token is verified and `userManagementInfo` is extracted from token 3. **FIXED**: No longer calls `detectUserManagementSystem()` 4. Uses the stored `userManagementInfo` from the token 5. Builds API key with correct format: - Keycloak: `{userKey}:{accountKey}:` (empty divisionId) - Cognito: `{userKey}:{accountKey}:{divisionId}` (numeric divisionId) ## Testing ### Manual Testing with Claude Desktop 1. Authenticate as a Cognito user (e.g., `david+saola@umbrellacost.com`) 2. Make API requests through MCP tools 3. Verify no 500 errors occur 4. Check server logs to confirm `userManagementInfo` is NOT being re-detected ### Expected Log Behavior **Before Fix**: You would see repeated logs like: ``` [DUAL-AUTH] ⚠️ OAuth user but userManagementInfo not set! Detecting user management system... [DUAL-AUTH] ✅ User management system detected: isKeycloak=true ← WRONG! ``` **After Fix**: You should see: ``` [DUAL-AUTH] OAuth Cognito - Built API key with divisionId: {uuid}:{accountKey}:{divisionId} ``` ## Build and Deploy ```bash # Build TypeScript npm run build # Restart server pkill -9 -f "node dist/index-dual.js" PORT=3003 node dist/index-dual.js ``` ## Verification Checklist - ✅ TypeScript compiles without errors - ✅ `userManagementInfo` stored in JWT token during authentication - ✅ `userManagementInfo` extracted from JWT token on subsequent requests - ✅ No re-detection calls to user-realm API during API requests - ✅ Cognito users get correct API key format (with numeric divisionId) - ✅ Keycloak users get correct API key format (with empty divisionId) ## Impact ### Users Affected - Cognito legacy users who exist in the user-realm API (migration state) - Example: `david+saola@umbrellacost.com` ### Users NOT Affected - Pure Keycloak UM 2.0 users (no Cognito account) - New users created directly in Keycloak ## Related Documents - `/INVESTIGATION_FINDINGS.md` - Root cause analysis - `/scripts/debug/test-both-auth-methods.cjs` - Auth method testing script - `/scripts/debug/investigate-user-realm-detection.cjs` - Realm detection test script ## Next Steps 1. ✅ Implementation complete 2. ⏳ Test with Cognito users through Claude Desktop 3. ⏳ Verify server logs show correct behavior 4. ⏳ Monitor for 500 errors (should be eliminated) 5. ⏳ Consider deprecating user-realm API detection entirely if this fix proves stable

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server