Voice WebSocket Authentication Test
Document Version: 1.0
Last Updated: December 31, 2025
Status: Test Documentation
Overview
This document describes how to test the voice WebSocket authentication implementation that extracts and validates JWT tokens from query parameters.
Test Requirements
- JWT Token: Valid JWT token from Entra External ID (MSAL)
- WebSocket Client: Python
websocketslibrary or browser WebSocket API - Backend Running: API server must be running and accessible
Test Scenarios
Test 1: WebSocket Connection with Valid Token
Objective: Verify that WebSocket accepts valid JWT token and creates authenticated SecurityContext.
Steps:
- Get JWT token from browser (MSAL Local Storage)
- Connect to WebSocket with token in query parameter:
ws://api.engram.work/api/v1/voice/voicelive/{session_id}?token={JWT} - Verify connection is established
- Check backend logs for authenticated user_id
Expected Result:
- WebSocket connection succeeds
- Backend logs show:
"VoiceLive WebSocket: Authenticated user {user_id} for session {session_id}" - SecurityContext created with
user_id = token.oid
Test Script:
python3 scripts/test-voice-websocket-auth.py --token <JWT_TOKEN>
Test 2: WebSocket Connection without Token (AUTH_REQUIRED=true)
Objective: Verify that WebSocket rejects connections without token when authentication is required.
Steps:
- Connect to WebSocket without token:
ws://api.engram.work/api/v1/voice/voicelive/{session_id} - Verify connection is rejected
Expected Result:
- WebSocket connection fails with status code 1008
- Reason: “Authentication required”
- Backend logs show:
"VoiceLive WebSocket: Authentication required but no token provided"
Test Script:
python3 scripts/test-voice-websocket-auth.py --test-no-token
Test 3: WebSocket Connection with Invalid Token
Objective: Verify that WebSocket rejects connections with invalid/expired tokens.
Steps:
- Use an invalid or expired JWT token
- Connect to WebSocket with invalid token
- Verify connection is rejected
Expected Result:
- WebSocket connection fails with status code 1008
- Reason: “Invalid token”
- Backend logs show:
"VoiceLive WebSocket: Token validation failed"
Test 4: Voice Session User Attribution
Objective: Verify that voice sessions are created with authenticated user_id.
Steps:
- Connect to WebSocket with valid token
- Send voice messages
- Check Zep memory for session creation
- Verify session has correct user_id
Expected Result:
- Zep session created with
user_id = token.oid - Session metadata includes user email/display_name
- Voice transcripts attributed to authenticated user
Manual Testing (Browser)
Step 1: Get JWT Token
- Open browser DevTools (F12)
- Go to Application > Local Storage
- Find key:
msal.{CLIENT_ID}.idtoken - Copy token value
Step 2: Test WebSocket Connection
// In browser console
const token = 'YOUR_JWT_TOKEN_HERE';
const sessionId = 'test-session-' + Date.now();
const wsUrl = `wss://api.engram.work/api/v1/voice/voicelive/${sessionId}?token=${encodeURIComponent(token)}`;
const ws = new WebSocket(wsUrl);
ws.onopen = () => {
console.log('✅ WebSocket connected');
// Send test message
ws.send(JSON.stringify({ type: 'agent', agent_id: 'elena' }));
};
ws.onerror = (error) => {
console.error('❌ WebSocket error:', error);
};
ws.onclose = (event) => {
console.log('WebSocket closed:', event.code, event.reason);
};
Automated Testing
Using Test Script
# Set token
export AUTH_TOKEN='your-jwt-token-here'
# Run test
python3 scripts/test-voice-websocket-auth.py
# Test without token (should fail if AUTH_REQUIRED=true)
python3 scripts/test-voice-websocket-auth.py --test-no-token
Expected Output
============================================================
Voice WebSocket Authentication Test
============================================================
URL: https://api.engram.work
Session ID: test-session-12345
Test 1: WebSocket connection with JWT token
------------------------------------------------------------
Connecting to WebSocket: wss://api.engram.work/api/v1/voice/voicelive/test-session-12345?token=...
✅ WebSocket connection established
✅ Test message sent
✅ Received response: ...
============================================================
Test Summary
============================================================
✅ Test 1 (with token): PASSED
✅ All tests passed!
Backend Log Verification
Check backend logs for authentication messages:
Success:
INFO: VoiceLive WebSocket: Authenticated user d240186f-f80e-4369-9296-57fef571cd93 for session test-session-12345
Failure (no token):
WARNING: VoiceLive WebSocket: Authentication required but no token provided for session test-session-12345
Failure (invalid token):
WARNING: VoiceLive WebSocket: Token validation failed for session test-session-12345: Invalid token
Troubleshooting
Issue: WebSocket connection fails immediately
Possible Causes:
- Token expired or invalid
- Token not properly URL-encoded
- Backend not running or unreachable
Solutions:
- Get fresh token from browser
- Verify token is properly encoded:
encodeURIComponent(token) - Check backend logs for error details
Issue: Connection succeeds but user_id is wrong
Possible Causes:
- Token validation not working correctly
- Fallback to POC user when AUTH_REQUIRED=false
Solutions:
- Verify
AUTH_REQUIRED=truein backend settings - Check backend logs for token validation messages
- Verify token contains correct
oidclaim
Related Documentation
docs/architecture/user-identity-flow-comprehensive.md- Complete user identity flowdocs/architecture/user-identity-fixes-required.md- Implementation detailsbackend/api/routers/voice.py- WebSocket handler implementation