My Grafana Installation is running on a Kubernetes Cluster, and I wanted a way to access the Grafana Dashboards over the internet without exposing the Ingress or web server directly. Since the site is using Cloudflare for DNS, I wanted to protect the login page with Cloudflare Access and only allow a couple of users by e-mail address to login.

Cloudflare Access provides JWT Tokens and an endpoint to read this information, Grafana also has authentication documentation on JWT authentication, but apparently the integration is broken.

Since the server is only available through Cloudflare Tunnel by using cloudflared, I figured I could just use Grafana’s Auth Proxy Authentication and use a header information about the logged-in email address which Cloudflare is providing to the origin server. Grafana could then just create an account for the user, skip the login form and present the dashboards. Wohoo!

Cloudflare Access & cloudflared

I’m not going to cover the configuration of Cloudflare Access and cloudflared itself here, but it’s important to note that this setup is only going to be secure when the web server with Grafana itself is not exposed to the public via another IP address, so make sure that there’s no ingress or service listening on the IP of a server or Kubernetes node, otherwise you could just make a request to the server, pass the header information with any e-mail address and log in.

When the server is configured with cloudflared, there’s no incoming connection allowed through other means except from Cloudflare itself, so they can put the Access login page in front of it and make sure only users which are allowed to access the application can get in.

Grafana config

It’s quite easy to configure Grafana to use the proxy authentication and take header information from Cloudflare Access. For this, you need to edit the grafana.ini file and add this block:

[auth.proxy]
enabled = true
header_name = cf-access-authenticated-user-email
header_property = email
auto_sign_up = true
enable_login_token = false

This enables the Proxy Authentication mechanism, uses the e-mail address from the header cf-access-authenticated-user-email which is provided by Cloudflare (when a user is successfully authenticated against Cloudflare Access that is), skips the Grafana login form and creates a user account automatically.

kube-prometheus-stack configuration

If you happen to use the prometheus-community/kube-prometheus-stack helm chart on Kubernetes, the configuration is slightly different since the YAML file needs to be updated. This would look like this then:

grafana:
grafana.ini:
auth.proxy:
enabled: true
header_name: cf-access-authenticated-user-email
header_property: email
auto_sign_up: true
enable_login_token: false