Reverse proxy: trusted header
Authenticate chmonitor via a reverse proxy identity header and shared secret — works with nginx, Kubernetes ingress, and any SSO auth_request setup.
Use this when you front chmonitor with a proxy that does its own authentication — nginx with an SSO module, a Kubernetes ingress with auth-url, or similar. The proxy sets a header with the authenticated user's identity; chmonitor trusts it only when a shared secret is also present.
- The upstream proxy authenticates the user and sets a header with their identity (e.g.
X-Forwarded-User: alice@example.com). - The proxy also sets a shared-secret header on every request.
- chmonitor checks the secret in constant time. If it matches, the identity header is trusted and the user is authenticated.
- Without
CHM_PROXY_AUTH_SECRETset, this mechanism is disabled. Any request missing the correct secret is treated as unauthenticated regardless of the identity header.
This prevents header forgery: a direct client hitting the Worker URL cannot fake authentication because they don't know the secret.
Prerequisites
A reverse proxy (nginx, Kubernetes ingress, or similar) that authenticates users upstream and can inject request headers before forwarding to chmonitor.
Setup
Prop
Type
CHM_AUTH_PROVIDER=proxy
CHM_PROXY_AUTH_HEADER=X-Forwarded-User # identity header (default)
CHM_PROXY_SHARED_SECRET_HEADER=X-Chm-Proxy-Secret # secret header (default)Set the secret out-of-band — never as a plaintext env file:
wrangler secret put CHM_PROXY_AUTH_SECRETlocation / {
# Your auth_request / SSO module sets $authenticated_user
auth_request /auth;
auth_request_set $authenticated_user $upstream_http_x_auth_user;
proxy_set_header X-Forwarded-User $authenticated_user;
proxy_set_header X-Chm-Proxy-Secret "the-same-long-random-secret";
proxy_pass http://chmonitor_upstream;
}The value of X-Chm-Proxy-Secret must match the CHM_PROXY_AUTH_SECRET you configured on the server.
Don't hardcode secrets in nginx config
Do not hardcode the secret value in your nginx config files. Load it at deploy time using environment variable substitution (envsubst), a secrets manager (e.g., HashiCorp Vault Agent), or a configuration management tool, and exclude the config from source control.
For k8s ingress with an external auth service, add the secret header in your ingress annotation or auth proxy config:
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header X-Forwarded-User $http_x_auth_request_user;
proxy_set_header X-Chm-Proxy-Secret "the-same-long-random-secret";Don't hardcode secrets in YAML manifests
Store the secret in a Kubernetes Secret and inject it into your auth proxy or ingress config at runtime rather than hardcoding it in YAML manifests that may be committed to source control. Example: kubectl create secret generic chm-proxy-secret --from-literal=value=<secret>, then reference it as an environment variable in your proxy container.
Verify
Send an authenticated request through the proxy and confirm data returns. A direct request to the Worker URL — bypassing the proxy, and therefore missing the correct secret header — must be treated as unauthenticated even if it carries an identity header.
Troubleshooting
Related
Authentication overview
Compare all auth providers and the two-layer model.
Cloudflare Access
Zero Trust JWT verification, no shared secret needed.
API keys
Add chm_ Bearer tokens for programmatic access.
Environment variables — Authentication
Every CHM_* auth variable and its default.
Feature permissions
Gate individual features to authenticated users.
Reverse proxy: Cloudflare Access
Authenticate chmonitor with Cloudflare Access — Zero Trust JWT verification, no shared secret needed.
Reverse proxy: trusted forwarded headers
Authenticate chmonitor via forwarded headers from oauth2-proxy, Authelia, Traefik ForwardAuth, or similar — full user profile with group-based access gating.