How to make one live dashboard public

Hi there,

(I know this would better fit to Tipps&Tricks, but I’m not allowed to post topics there.)

I want to make one (or more) live dashboard public, which is not supported out of the box as other users already complained and now [even made a new feature request] (https://github.com/grafana/grafana/issues/14473). Reading the documentation (and having a reverse proxy as [nginx] (http://nginx.org/) available, this feature indeed is possible.

Security precaution: Making a dashboard public will not just only make “that dashboard” public, but also the API that has access to all datasources/tables that this dashboard uses.

How to do this setup:
First step: Setup Grafana as you usually would, I installed it on internal port 3000 (not publicly available) - with this setup I would advise you to do so for security reasons (explained later).

Second step: Setup the public user (remember that name) with Configuration -> Server Admin -> Users -> Add new user, Password can be random and doesn’t have to be remembered. Make sure this user is configured only as Viewer. Edit all Dashboards you don’t want to share and remove default Viewer Permission for Viewer Role (sadly you also have to remember to do that for every new created dashboard, keep that in mind!).

Third step: Configure Grafana to use HTTP Header field X-WEBAUTH-USER for user authentication. Grafana uses that user as authenticated user - so you should make sure that this field only gets set by your server, thus your Grafana instance from first step shouldn’t be accessible directly!

You can either set these environment variables:

GF_AUTH_PROXY_AUTO_SIGN_UP=false
GF_AUTH_PROXY_ENABLED=true

Or you modify your grafana config and set:

[auth.proxy]
auto_sign_up = false
enabled = true

You can use Grafana Configuration -> Server Admin -> Settings to make sure these settings got applied.

Fourth step: Configure your nginx to provide two access ways to Grafana.

One traditional with Grafana authentication (I used port 3001 for that - I also included SSL not written here for clarity):

server {
    listen       3001;
    location / {
        proxy_pass                            http://localhost:3000/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
        proxy_set_header X-WEBAUTH-USER       "";
    }
}

Here I explicitly unset the X-WEBAUTH-USER header, thus no user can forge this header, thus exposing this instance to the public is safe. Grafana will show the usual login fields for logging in.

The other access is the public one, I used port 3002 for that.
Caution: If you don’t want to mix up the logins, I would advise you to use another (sub?)domain for that instance, otherwise Grafana will mix up cookies and logins (explained later).

server {
    listen       3002;
    location / {
        proxy_pass                            http://localhost:3000/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
        proxy_set_header X-WEBAUTH-USER       <your public username>;
    }
}

Viola, you are done and can share dasboards (or single panels) to the world.

Note: regarding the different domain names for both access ways:
When you use the same domain for both ways, things like this can happen: You login at private instance, want to edit something. For testing you open the public one. Now you go back to private instance and want to save - that will not work, because the visit at public instance will set your user cookie to the public user, which doesn’t have write access. So either don’t visit public instance during edits, or separate both by hostname.

Have fun :slight_smile:

2 Likes

Just be advices that even though the public user will only be able to access the specified dashboard as a viewer role they will still be able to issue any query to any of the orgs datasources.

There are no per query restrictions so viewer user can access all data (technically via the query http).

How exactly do I configure nginx to provide two access ways to Grafana.

… and it happened: https://www.derstandard.de/story/2000115960650/datenleck-bei-coronavirus-seite-des-gesundheitsministeriums
It’s in german, so a short summary: Austrian government put up a webpage about SARS-CoV-2 spread in its country, summarizing the data using Grafana.
Data in the database configured and used for Grafana was more detailed (didn’t include names, but information like sex, age and district for each of the infected peoples) which thus were accessible if you know how to do it.

That’s a bit difficult, because as soon as you modify Grafana config for proxy auth as described above, Grafana turns off internal user management, and you can’t set up new users. (figured this out some months after writing the tutorial as I wanted to add a new user)

So finally I ended up with two Grafana instances, sharing data and configuration - and getting configuration differences through environment variables.
In detail I spun up two docker containers (with shared data storage), and modified nginx configuration above to use the one docker instance for user authentication, and the other docker instance for proxy authentification.

Because of your link in German I think you can speak German? Maybe that would be easier to write. It doesn’t matter if I can’t add a new user, but I don’t know exactly what to change in nginx. The previous steps worked