chmonitor
Authentication

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_SECRET set, 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_SECRET
location / {
  # 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

On this page