Files
Toju/agents-docs/features/authentication.md
2026-06-05 18:34:01 +02:00

2.9 KiB

Authentication

Session-token authentication for the signaling server and product client.

Trust boundaries

Surface Identity proof Notes
Signaling server REST (mutations) Authorization: Bearer <token> Actor user IDs in request bodies are ignored; server derives authUserId from the token
Signaling server REST (discovery) None GET /api/servers, featured/trending/search remain public
Signaling server WebSocket identify.token Connections must identify before any other message type
Electron Local API Separate in-memory bearer tokens Proxies login to allowed signaling servers only
Product client local DB OS user account SQLite and attachments are plaintext at rest

Login / register response

{
  "id": "<uuid>",
  "username": "alice",
  "displayName": "Alice",
  "token": "<opaque-hex>",
  "expiresAt": 1710000000000
}
  • Tokens are opaque 64-character hex strings stored in server SQLite (session_tokens).
  • Default TTL: 24 hours (SESSION_TOKEN_TTL_MS env override supported).
  • Passwords are stored with bcrypt; legacy SHA-256 hashes are upgraded transparently on successful login.

Protected REST routes

Require Authorization: Bearer:

  • PUT/POST/DELETE under /api/servers/* (except public GET)
  • PUT /api/requests/:id
  • Plugin-support mutations under /api/servers/:serverId/plugins/*
  • /api/users/device-tokens/*
  • POST /api/users/logout

WebSocket identify contract

{
  "type": "identify",
  "token": "<session-token>",
  "oderId": "<user-id>",
  "displayName": "Alice",
  "connectionScope": "ws://host:3001"
}
  • oderId must match the token's user id when provided.
  • Server responds with auth_error or auth_required when authentication fails.

Client storage

The product client stores tokens per signaling-server base URL in localStorage (metoyou.authTokens). An HTTP interceptor attaches the bearer token to /api/* requests targeting that server.

Persisted local user state (metoyou_currentUserId + IndexedDB/SQLite profile) is not sufficient to use chat or presence. On startup, loadCurrentUser$ requires a non-expired session token for the user's home/active signaling server (or any stored token as a fallback). Missing or rejected tokens dispatch SESSION_EXPIRED and redirect to /login. WebSocket auth_required / auth_error responses trigger the same path.

Security considerations

  • Rate limits: login/register (100 / 15 min), server join (30 / min).
  • CORS allowlist: optional corsAllowlist in server/data/variables.json or CORS_ALLOWLIST env (comma-separated). Empty allowlist keeps permissive CORS for local development.
  • Push-token routes require bearer auth and user-id match.
  • RTC relay: direct-message/direct-call types always relay; server-icon types require shared server membership; WebRTC offer/answer/ice remain open for cross-server DM WebRTC.