Clerk
Authenticate chmonitor users with Clerk — browser sign-in via __session cookie, with optional public read-only mode and MCP OAuth support.
Use Clerk when you want browser-based sign-in with user accounts. The browser authenticates via a Clerk __session cookie, verified networklessly on each /api/v1/* call. The MCP server additionally accepts Clerk OAuth bearer tokens.
- Browser clients sign in through Clerk's hosted UI.
- The
__sessioncookie is sent automatically same-origin and verified on the server using the Clerk secret key — no network call per request. - The publishable key must be present at build time so the client-side gate enables Clerk UI (sign-in button, user menu). The secret key is read at runtime.
Prerequisites
A Clerk application with its publishable and secret keys. The client VITE_AUTH_PROVIDER / VITE_CLERK_PUBLISHABLE_KEY values are derived from the canonical CHM_* names at build time, so set them before bun run build. CLERK_SECRET_KEY (the sk_... key) is the runtime secret and stays server-side.
Migrating from Next.js?
If migrating from the legacy Next.js app, see Migrate to v0.3 for the NEXT_PUBLIC_* → VITE_* rename.
Setup
Prop
Type
Create a Clerk application
Create a Clerk application at clerk.com.
Copy your keys
Copy the Publishable key (pk_live_...) and Secret key (sk_live_...) from the Clerk dashboard.
Set build-time env vars
Set these before building the client (the client VITE_* values are derived from them):
CHM_AUTH_PROVIDER=clerk
CHM_CLERK_PUBLISHABLE_KEY=pk_live_...Set runtime env vars
Set these on the server (or as Worker secrets):
CHM_AUTH_PROVIDER=clerk
wrangler secret put CLERK_SECRET_KEY # paste sk_live_...Rebuild and redeploy
The sign-in button appears in the header after redeploy.
Verify
After redeploy, the sign-in button appears in the header. Sign in through Clerk's hosted UI, then confirm data loads on the dashboard — an authenticated __session cookie satisfies the guard on every /api/v1/* call.
Clerk OAuth for MCP
The MCP server at /api/mcp also accepts Clerk OAuth bearer tokens. Clerk acts as the authorization server (login, consent, dynamic client registration); chmonitor is the resource server and verifies tokens via Clerk's REST introspection. This lets MCP clients use an OAuth flow instead of a chm_ API key. It uses the same CLERK_SECRET_KEY — no extra configuration needed.
See MCP Server for connection details.
Gate features to authenticated users
Most features are public even with Clerk enabled. The AI agent (agent) and
control actions (actions — KILL QUERY, OPTIMIZE TABLE) default to
authenticated, so they require sign-in. To change a feature's access:
CHM_FEATURE_AGENT_ACCESS=public # loosen the agent to public
CHM_FEATURE_TABLES_ACCESS=authenticated # require sign-in for tablesSee Feature Permissions for all feature ids and options.
Public read-only mode
By default, Clerk gates every /api/v1/* request — an anonymous visitor sees
the dashboard shell but no data (every data call returns 401). Set
CHM_CLERK_PUBLIC_READ to let anonymous visitors view read-only monitoring
content while keeping sign-in required for writes:
CHM_AUTH_PROVIDER=clerk
CHM_CLERK_PUBLIC_READ=true # runtime / Worker varAccess is then split along a read / write boundary:
- Reads — predefined monitoring data (overview, queries, tables, metrics, charts, schema browsing) — serve to anonymous visitors.
- Writes — the AI agent, control actions (KILL QUERY, OPTIMIZE TABLE), and
arbitrary SQL execution (SQL Console / explorer query) — still return
401for anonymous callers. Running attacker-chosen SQL is treated as a write even though it runs read-only, because it is a far more powerful capability than a fixed registry query. - API keys (
chm_bearer tokens) and signed-in Clerk users get full read + write.
Anonymous capability matrix
| Auth mode | Anonymous read | Anonymous write |
|---|---|---|
none | ✅ | ✅ (everyone is authenticated) |
clerk + CHM_CLERK_PUBLIC_READ=true | ✅ | ❌ |
clerk (default) | ❌ | ❌ |
proxy | ❌ | ❌ (proxy authenticates upstream) |
The flag only applies to the clerk provider — none is already fully public and
proxy fronts its own auth. It is off by default, so existing locked-down Clerk
deployments are unchanged. The client reads these flags from GET /api/v1/config
(capabilities.read / capabilities.write) to decide what to surface.
Related
Authentication overview
Compare all auth providers and the two-layer model.
API keys
Add chm_ Bearer tokens for programmatic access alongside Clerk.
MCP server
Connect MCP clients with Clerk OAuth or chm_ tokens.
Environment variables — Authentication
Every CHM_* auth variable and its default.
Feature permissions
Gate individual features to authenticated users.