Files
IRC-kosmi-relay/AUTH_DISCOVERY.md
cottongin dd398c9a8c sync
2025-11-01 21:00:16 -04:00

5.5 KiB

Kosmi Authentication Discovery

Date: November 1, 2025

Summary

Investigation into Kosmi's email/password authentication mechanism reveals a non-standard implementation that requires further reverse engineering.

Findings

1. GraphQL API Analysis

Endpoint: https://engine.kosmi.io/

Available Mutations:

$ ./bin/test-introspection | jq '.data.__schema.mutationType.fields[] | .name'
"anonLogin"
"slackLogin"

Key Discovery: There is NO login, emailLogin, or passwordLogin mutation in the GraphQL API.

2. Anonymous Login (Working)

The anonLogin mutation works and is currently implemented:

mutation {
  anonLogin {
    token
    user {
      id
      displayName
    }
  }
}

3. Email/Password Login (Mystery)

Observations:

  • Email/password login works successfully in the browser
  • After login, a JWT token appears in localStorage with key "token"
  • Example token payload:
    {
      "aud": "kosmi",
      "exp": 1793465205,
      "iat": 1762015605,
      "iss": "kosmi",
      "jti": "1c7f9db8-9a65-4909-92c0-1c646103bdee",
      "nbf": 1762015604,
      "sub": "4ec0b428-712b-49d6-8551-224295 45d29b",
      "typ": "access"
    }
    
  • Token expires in ~1 year
  • Algorithm: HS512

REST API Endpoints Found:

# Both return 400 with empty error message
POST https://engine.kosmi.io/auth/login
POST https://engine.kosmi.io/login

# Response format:
{
  "errors": [
    {
      "message": ""
    }
  ]
}

Tested Request Formats (all failed):

{"email": "...", "password": "..."}
{"username": "...", "password": "..."}

4. Possible Authentication Mechanisms

Theory 1: Client-Side JWT Generation

  • The browser might be generating JWTs client-side
  • This would be a security concern but would explain why there's no server endpoint
  • Would require extracting the signing key from the JavaScript bundle

Theory 2: Hidden Authentication Flow

  • The password might be hashed/processed client-side before transmission
  • Could be using SRP (Secure Remote Password) or similar protocol
  • Would require analyzing the minified JavaScript

Theory 3: Separate Authentication Service

  • Kosmi might use a third-party auth service (not Firebase/Auth0/Cognito - those were checked)
  • The service might not be directly accessible via HTTP

Theory 4: WebSocket-Based Authentication

  • Authentication might happen over the WebSocket connection
  • The REST endpoints might be red herrings

5. Browser Monitoring Attempts

Multiple attempts were made to capture the authentication request:

  • Playwright network interception (failed - page reloads cleared interceptors)
  • JavaScript fetch() hooking (failed - page reloads)
  • Browser MCP tools (successful login but couldn't capture request body)

Successful Test:

  • Used browser MCP tools to log in with credentials: email@email.com / password
  • Login succeeded
  • Token appeared in localStorage
  • But the actual HTTP request was not captured

Current Implementation Status

Working

  • Anonymous authentication via anonLogin GraphQL mutation
  • Token storage and usage for WebSocket connections
  • Automatic reconnection with token refresh

Not Working

  • Email/password authentication
  • Token refresh (no refreshToken mutation found in GraphQL API)

Recommendations

Option 1: Anonymous-Only (Current State)

  • Document that only anonymous login is supported
  • Users can still connect to rooms anonymously
  • This is sufficient for basic bot functionality

Option 2: Manual Token Provision

  • Allow users to provide a pre-obtained token in the config
  • Users would log in via browser, extract token from localStorage
  • Bot uses the provided token directly
  • Pros: Simple, works immediately
  • Cons: Tokens expire (though they last ~1 year), manual process

Option 3: Deep Reverse Engineering

  • Download and deobfuscate core.js (~several MB)
  • Find the authentication logic
  • Replicate it in Go
  • Pros: Full automation
  • Cons: Time-consuming, fragile (breaks if Kosmi updates their code)

Option 4: Browser Automation

  • Use Playwright/Chromedp to automate browser login
  • Extract token from localStorage after login
  • Use token for bot connection
  • Pros: Works with any auth changes
  • Cons: Requires browser, more complex setup

Next Steps

  1. Immediate: Implement Option 2 (Manual Token Provision)

    • Add Token field to config
    • If provided, skip anonLogin and use the token directly
    • Document how users can extract their token
  2. Future: Attempt Option 3 if user provides more information

    • User might have insights into how their own auth works
    • Could provide network HAR file from browser DevTools
  3. Alternative: Contact Kosmi

    • Ask if they have a documented API for bots
    • Request official authentication method

Test Credentials Used

  • Email: email@email.com
  • Password: password
  • These credentials successfully logged in via browser

Files Created During Investigation

  • cmd/test-login/main.go - Test GraphQL login mutations
  • cmd/test-introspection/main.go - GraphQL schema introspection
  • cmd/monitor-auth/main.go - Playwright-based traffic monitoring (had issues)

Conclusion

Kosmi's email/password authentication uses a non-standard mechanism that is not exposed through their GraphQL API. Further investigation would require either:

  1. Deep analysis of their minified JavaScript
  2. User providing more information about the auth flow
  3. Implementing manual token provision as a workaround