Skip to content

User Connections (Server Storage)

Save personal ClickHouse hosts to the server so they sync across devices when signed in with Clerk.

Feature id(none — gated by env flags)
Default accessAuthenticated Clerk users only
Requires authYes (Clerk)
StorageD1 (Cloudflare) or PostgreSQL

When enabled, users can choose Save to server in the Add Host dialog. Credentials are encrypted at rest with CHM_CONNECTIONS_ENCRYPTION_KEY and never returned to the client after save.

Browser-only storage remains available when server storage is disabled or the user prefers a local connection.

  1. Set auth to Clerk (CHM_AUTH_PROVIDER=clerk, VITE_AUTH_PROVIDER=clerk).
  2. Configure a database backend:
    • Cloudflare Workers: CONVERSATIONS_D1 binding (shared D1 database; migration 0002_user_connections.sql).
    • Node / K8s: DATABASE_URL or POSTGRES_URL.
  3. Set feature flags:
    Terminal window
    VITE_FEATURE_USER_CONNECTIONS_DB=true
    CHM_FEATURE_USER_CONNECTIONS_DB=true
  4. Set the encryption secret (32-byte key, base64-encoded):
    Terminal window
    wrangler secret put CHM_CONNECTIONS_ENCRYPTION_KEY
  5. Redeploy the dashboard.

The Add Host dialog shows an enabled Save to server toggle when all requirements are met. Otherwise it displays a note with a link to this page.

  • Per-user isolation: Each connection row is keyed by the signed-in Clerk userId. List, read, update, delete, and chart/table proxy routes all resolve auth first and query with WHERE user_id = ?. Guessing another user’s connectionId returns 404 — never their credentials.
  • Not org-shared: Connections belong to the individual Clerk account, not the whole organization. Two teammates each see only their own server-stored hosts.
  • Passwords are encrypted with AES-256-GCM before writing to D1/Postgres.
  • API routes return connection metadata only; passwords are never echoed after create.
  • Browser-stored hosts use short-lived session tokens so passwords are not sent on every chart/table request.
  • The client cache for server connections is scoped per Clerk user, cleared on sign-out / account switch, and excluded from persisted localStorage so another login on the same browser cannot flash a prior user’s host list.
  • Shared ?host=-1000 URLs only work for the same signed-in user with that connection saved.