Authentication
chmonitor has two independent auth layers that work together on every /api/v1/* route:
- Auth provider — one of
none,clerk,proxy, ortrusted. Controls whether browser sessions are authenticated. Set withCHM_AUTH_PROVIDER(server) andVITE_AUTH_PROVIDER(client, build-time inlined). - API key layer — always active when
CHM_API_KEY_SECRETis set. Authenticates programmatic clients (MCP, scripts, CI) with signedchm_Bearer tokens, independent of the provider.
A request is allowed when either layer accepts it. The only fully public setup is CHM_AUTH_PROVIDER=none with no CHM_API_KEY_SECRET.
Summary
Section titled “Summary”| Method | Who reads it | Browser / proxy auth | curl / MCP auth |
|---|---|---|---|
Public (none) | — | open | none needed |
| API key | Provider-agnostic; active when CHM_API_KEY_SECRET set | — | Authorization: Bearer chm_… |
| Clerk | clerk provider | Clerk __session cookie | Clerk token or chm_ key |
| Clerk OAuth (MCP only) | MCP server | — | OAuth bearer token |
| Proxy → Cloudflare Access | proxy provider | Cf-Access-Jwt-Assertion JWT | — |
| Proxy → trusted header (bare subject) | proxy provider | X-Forwarded-User + shared secret | shared secret header |
| Proxy → trusted headers (full profile) | trusted provider | forwarded headers (oauth2-proxy / Dex / Authelia) | shared secret header |
How enforcement decides
Section titled “How enforcement decides”For each /api/v1/* request, in order:
- If
CHM_AUTH_PROVIDER=noneandCHM_API_KEY_SECRETis not set → allow (public). - The key-issuance route
/api/v1/auth/api-keyis exempt (it has its own auth). - A valid
chm_Bearer token → allow. - The active provider’s check runs; if it authenticates → allow.
- Otherwise →
401 { "error": "Authentication required" }.
All paths fail closed: a missing config or verification error resolves to “not authenticated”.
Which one should I use?
Section titled “Which one should I use?”| Situation | Recommended setup |
|---|---|
| Local dev or internal network, no login needed | Public (none) — default |
| Hosted dashboard with user accounts and sign-in | Clerk |
| Behind Cloudflare Access | Proxy — cloudflare-access |
| Behind nginx/SSO with a bare identity header | Proxy — trusted-header |
| Behind oauth2-proxy / Dex / Authelia / Traefik ForwardAuth | Trusted (trusted) |
| MCP clients, scripts, CI pipelines | API key (CHM_API_KEY_SECRET) — add alongside any provider |
Provider pages
Section titled “Provider pages”- Public / no auth — default open dashboard
- API keys —
chm_Bearer tokens for programmatic access - Clerk — browser sign-in with Clerk sessions
- Cloudflare Access —
proxyprovider; Cloudflare Access JWT verification - Trusted header —
proxyprovider; bare subject via shared secret - Trusted proxy —
trustedprovider; full profile from forwarded headers (oauth2-proxy, Dex, Authelia)