> ## Documentation Index
> Fetch the complete documentation index at: https://cloud-docs.mentra.glass/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication flow

# Getting Connected: Authentication Flow

Let's follow a user named Alex as they open the MentraOS mobile app and connect their smart glasses to the cloud. This journey shows how authentication works and how WebSocket connections are established.

## Step 1: Mobile App Login

When Alex opens the MentraOS app on their phone:

1. **User Authentication**
   * Alex logs in with their email/password
   * The app authenticates with our auth service
   * App receives a `coreToken` (JWT) that identifies Alex

2. **What's in the coreToken?**
   ```json theme={null}
   {
     "sub": "alex@example.com",  // User's email
     "exp": 1234567890,          // Expiration time
     "iat": 1234567800           // Issued at time
   }
   ```

## Step 2: Glasses Connect via Phone

Once authenticated, the mobile app:

1. **Establishes Bluetooth connection** with Alex's smart glasses
2. **Opens WebSocket to cloud** at `wss://cloud.mentraos.com/glasses-ws`
3. **Sends the coreToken** in the Authorization header:
   ```
   Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
   ```

## Step 3: WebSocket Handshake

Now the magic happens in our cloud:

### 1. Connection Arrives at WebSocketService

```typescript theme={null}
// In WebSocketService.ts
app.ws('/glasses-ws', (ws, req) => {
  // Extract and verify the JWT token
  const token = req.headers.authorization?.split(' ')[1];
  const decoded = jwt.verify(token, JWT_SECRET);
  const userEmail = decoded.sub;
  
  // Hand off to GlassesWebSocketService
  glassesWebSocketService.handleConnection(ws, userEmail);
});
```

### 2. GlassesWebSocketService Takes Over

```typescript theme={null}
// In GlassesWebSocketService.ts
handleConnection(ws: WebSocket, userEmail: string) {
  // Send connection acknowledgment
  ws.send(JSON.stringify({
    type: 'CONNECTION_ACK',
    sessionId: generateSessionId()
  }));
  
  // Create or retrieve UserSession
  let session = SessionStorage.getSession(userEmail);
  if (!session) {
    session = new UserSession(userEmail, ws);
    SessionStorage.addSession(session);
  } else {
    // Reconnection - update WebSocket
    session.updateWebSocket(ws);
  }
}
```

### 3. The First Message Exchange

Mobile app must send CONNECTION\_INIT within 30 seconds:

```typescript theme={null}
// From mobile app (defined in glasses-to-cloud.ts:15-19)
{
  type: "CONNECTION_INIT",
  userId?: "alex@example.com",  // Optional user ID
  coreToken?: "eyJhbGci..."     // Optional auth token
}
```

Cloud responds with CONNECTION\_ACK:

```typescript theme={null}
// From cloud (defined in cloud-to-glasses.ts:19-23)
// Sent from websocket-glasses.service.ts:558-566
{
  type: "CONNECTION_ACK",
  sessionId: "alex-123456",      // Unique session ID
  userSession: {                 // Partial<UserSession> from transformUserSessionForClient
    userId: "alex@example.com",
    startTime: "2024-01-01T00:00:00Z",
    activeAppSessions: ["com.app1", "com.app2"],
    loadingApps: [],
    appSubscriptions: {
      "com.app1": ["audio", "transcription"],
      "com.app2": ["notification"]
    },
    requiresAudio: true,
    minimumTranscriptionLanguages: ["en-US"],
    isTranscribing: true
  },
  timestamp: "2024-01-01T00:00:00Z"
}
```

## Step 4: Heartbeat Keeps Connection Alive

Every 10 seconds, the cloud sends a ping to check if the connection is alive:

```typescript theme={null}
// In UserSession.ts
private startHeartbeat() {
  this.heartbeatInterval = setInterval(() => {
    if (this.websocket.readyState === WebSocket.OPEN) {
      this.websocket.ping();
    }
  }, 10000);
}
```

If the mobile app doesn't respond to pings, the connection is considered dead and cleaned up.

## Step 5: Handling Reconnections

What happens when Alex's phone loses connection?

1. **Grace Period** (30 seconds)
   * UserSession remains in memory
   * Apps stay in "resurrecting" state
   * No data is lost

2. **Reconnection Within Grace Period**
   * Same coreToken is used
   * UserSession is retrieved from SessionStorage
   * WebSocket is updated with new connection
   * Apps are notified of reconnection
   * Everything continues seamlessly

3. **Reconnection After Grace Period**
   * New UserSession is created
   * Apps must be restarted
   * Previous state is lost

## Security Considerations

1. **JWT Validation**
   * All tokens are verified for signature
   * Expired tokens are rejected
   * Invalid tokens result in CONNECTION\_ERROR

2. **User Isolation**
   * Each UserSession is keyed by email
   * No cross-user data access
   * Sessions are completely isolated

3. **Connection Limits**
   * One active glasses connection per user
   * New connections replace old ones
   * Prevents connection flooding

## Common Connection Errors

```typescript theme={null}
// Connection rejected - invalid token
{
  type: "CONNECTION_ERROR",
  error: "Invalid authentication token"
}

// Connection rejected - expired token
{
  type: "CONNECTION_ERROR", 
  error: "Token expired"
}

// Connection timeout - no CONNECTION_INIT
{
  type: "CONNECTION_ERROR",
  error: "Connection initialization timeout"
}
```

## What's Next?

Now that Alex is connected, the cloud creates a UserSession for them. This session is their personal command center in the cloud. Let's explore [UserSessions](./3-user-sessions.md) next!
