Skip to content

Migrate settings auth from encrypted tokens to Redis sessions#152

Closed
buremba wants to merge 6 commits into
mainfrom
claude/review-settings-token-security-yDPMX
Closed

Migrate settings auth from encrypted tokens to Redis sessions#152
buremba wants to merge 6 commits into
mainfrom
claude/review-settings-token-security-yDPMX

Conversation

@buremba
Copy link
Copy Markdown
Member

@buremba buremba commented Mar 4, 2026

Description

This PR replaces the encrypted token-based authentication system for settings pages with a server-side Redis session approach. Instead of embedding sensitive context in encrypted URL tokens, authentication now uses opaque session IDs stored in Redis, improving security and simplifying token management.

Key Changes

New Session Infrastructure:

  • Added AuthSessionStore - Redis-backed session store for managing auth context with configurable TTL
  • Added OAuthIdentityStore - Maps OAuth provider identities to platform users
  • Added SettingsOAuthProvider - Handles OAuth flows for settings authentication

Authentication Flow Updates:

  • Settings pages now use session IDs (?s=<uuid>) instead of encrypted tokens (#st=...)
  • Session context (userId, agentId, channelId, platform) stored server-side in Redis
  • Telegram WebApp auth creates Redis sessions instead of encrypted tokens
  • OAuth identity verification integrated with session store

Type Changes:

  • Renamed SettingsTokenPayload to SettingsSessionPayload throughout codebase
  • Updated imports to use new session-based functions (buildSessionUrl, getSessionStore)
  • Removed token generation functions (generateSettingsToken, generateChannelSettingsToken)

Affected Components:

  • Settings routes (/routes/public/settings.ts) - now session-based
  • Agent config routes - updated to use session verification
  • Slack/WhatsApp/Telegram message handlers - generate session URLs instead of tokens
  • Settings auth utilities (settings-auth.ts) - session verification instead of token verification
  • Internal settings link routes - use Redis sessions for worker-generated links

Code Quality:

  • Standardized indentation (spaces to tabs) across multiple files
  • Removed unused token encryption/decryption logic
  • Simplified auth flow by eliminating token payload complexity

Type of Change

  • New feature (server-side session management)
  • Breaking change (authentication mechanism changed)
  • Refactoring (auth infrastructure redesign)

Testing

  • Existing session verification tests should pass
  • OAuth identity mapping tests cover new identity store
  • Settings page rendering tests verify session payload handling
  • Integration tests for Slack/WhatsApp/Telegram auth flows

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • No new warnings introduced
  • Type changes documented (SettingsTokenPayload → SettingsSessionPayload)

Related Issues

N/A

Additional Notes

This is a security-focused refactor that eliminates the need to transmit sensitive context in URLs. Session IDs are opaque and short-lived, with all context stored securely server-side in Redis. The change maintains backward compatibility at the API level while improving the underlying authentication mechanism.

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq

claude added 6 commits March 4, 2026 14:56
The GetSettingsLink fallback path returned the raw settings URL (containing
the encrypted token) directly to the worker/agent in the tool response text
and logged it. A compromised or jailbroken agent could exfiltrate this token
to access the user's settings page.

Fix: gateway fallback now returns type:"settings_link" (same as the normal
path) instead of the raw URL. Worker fallback no longer logs or returns the
URL to the agent.

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq
…ating endpoints

Apply the same defense-in-depth pattern established for settings-link to all
gateway endpoints that generate authenticated URLs:

Gateway side (never return raw URLs to worker):
- /internal/mcp-login: fallback no longer returns loginUrl, returns
  type:"mcp_login_link" with safe message instead
- /internal/integrations/connect: fallback no longer returns oauthUrl,
  returns safe message matching the interactionService path

Worker side (never pass raw gateway messages to agent):
- ConnectService MCP fallback: checks response type instead of blindly
  passing data.message (which could contain URLs)
- ConnectService OAuth path: uses fixed messages instead of passing
  result.message from gateway

Principle: the gateway delivers sensitive links to users via
interactionService (native platform buttons). The worker/agent never
needs to see the actual URL.

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq
…gnostic OAuth

Consolidate all auth token systems into a single pattern: server-side
Redis sessions with opaque session IDs in URLs. No encrypted tokens
travel through URLs anymore.

New components:
- AuthSessionStore: Redis-backed session store (key: auth:session:{uuid})
  Replaces AES-256-GCM encrypted token generation for settings links
  and integration OAuth init URLs.
- OAuthIdentityStore: Maps OAuth provider identities to platform users.
  First access establishes mapping (trusted via chat delivery), subsequent
  accesses verify it.
- SettingsOAuthProvider: Configurable OAuth for settings page identity
  verification. Provider-agnostic — any OAuth2 provider works via env vars
  (SETTINGS_OAUTH_AUTH_URL, _TOKEN_URL, _CLIENT_ID, _CLIENT_SECRET,
  _USERINFO_URL, _SCOPES, _PROVIDER_NAME). Uses existing GenericOAuth2Client.

Settings flow changes:
- settings-link.ts: createSession() instead of generateSettingsToken()
- settings-auth.ts: Redis lookup instead of token decryption (now async)
- settings.ts: Handles ?s= session param, OAuth redirect/callback,
  Telegram initData creates Redis session instead of synthetic encrypted token

Integration OAuth changes:
- oauth-module.ts: createInitSession() replaces generateSecureToken().
  Init URLs use ?s=<sessionId> instead of ?token=<encrypted>.
  Metadata stored in auth:session:meta:{sessionId} alongside session.
- routes.ts: Uses oauthModule.createInitSession() for connect flow.

All verifySettingsSession() callers updated to use await (now async).
Legacy generateSettingsToken/verifySettingsToken kept for backward compat
(Slack events, WhatsApp handlers, built-in commands — to migrate later).

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq
The session bootstrap page now reads the `s` hash param (matching
buildSessionUrl) and sends `sessionId` to POST /settings/session.
Falls back to legacy `st` and `token` params for backward compat.

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq
…ts and legacy token callers

Consolidate all settings URL generation to use ?s= query params with
Redis sessions. Remove hash fragment patterns (#s=, #st=, #token=),
backward compatibility fallbacks, and all usage of generateSettingsToken,
generateChannelSettingsToken, buildSettingsUrl, verifySettingsToken.
Rename bootstrap page to Telegram-only since that's the sole use case.

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq
Delete generateSettingsToken, verifySettingsToken, buildSettingsUrl,
SETTINGS_TOKEN_HASH_PARAM, SettingsTokenPayload alias, and
SettingsTokenOptions from token-service.ts. Update all test files
to use session-based auth (?s= query param) instead of encrypted tokens.

https://claude.ai/code/session_01QhKDdik3bc5hkMecqJHFcq
@buremba
Copy link
Copy Markdown
Member Author

buremba commented Mar 5, 2026

Getting rid of AI slop

@buremba buremba closed this Mar 5, 2026
buremba added a commit that referenced this pull request May 17, 2026
Includes:
- #150 PATH-based agent detection (replaces MCP session inference)
- #152 auto-pick default agent when defaultAgent is unset
- #155 distinct SF Symbol icons per CLI agent kind
- #154 WATCHERS section in menubar with last-fired + manual trigger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants