Grafana jwt auth issue with jwt token

  • What Grafana version and what operating system are you using?
    I am using grafana: 13.0.2

  • What are you trying to achieve?
    Implement jwt auth in grafana by passing jwt token in headers

  • How are you trying to achieve it?
    I was testing this feature, so I created a node server with the following details:

  // server.js
  const express = require('express');
  const { createProxyMiddleware } = require('http-proxy-middleware');

  const app = express();
  app.use('/', createProxyMiddleware({
  target: 'my_grafana_localhost_url',
  changeOrigin: true,
  onProxyReq: (proxyReq, req, res) => {
  const jwtToken = "my_jwt_token";
  proxyReq.setHeader('X-JWT-Assertion', `${jwtToken}`);
  }
  }));

  app.get('/wrapper', (req, res) => {
  res.send(`   <!DOCTYPE html>     <html>     <head>       <title>Grafana Dashboard via JWT Proxy</title>       <style>         body, html { margin:0; padding:0; height:100%; }         iframe { width:100%; height:100%; border:none; }       </style>     </head>     <body>       <!-- IMPORTANT: iframe src points to /d/... directly -->       <iframe src="/d/dashboard_id?orgId=1"></iframe>     </body>     </html> `);
  });

  app.listen(8081, () => {
  console.log('JWT proxy running at http://localhost:8081');
  });

and the minimal grafana conf are:

  [auth.jwt]

  enabled = true

  header_name = X-JWT-Assertion

  username_claim = sub

  email_claim = sub

  auto_sign_up = false # because I have created these users in grafana and want to validate them against their dashboard permissions
  • What happened?
    It keeps sending me to login page

  • What did you expect to happen?
    I wanted the user to log in with the jwt token inside the iframe

  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.
    No errors, not even in inspect elements (as far as I can find)

  • Did you follow any online instructions? If so, what is the URL?
    yes this

The config you’ve shared doesn’t show a JWT verification key source (jwk_set_file, key_file, jwk_set_url, etc.). If one isn’t configured, Grafana cannot validate the JWT signature, so JWT authentication will fail. For browser requests, this commonly results in the login page being shown.

Also make sure you have:

[auth.jwt]
enable_login_token = true

[security]
allow_embedding = true

enable_login_token allows Grafana to create a login session after successful JWT authentication, which is typically required for browser/iframe access. allow_embedding is required if you’re embedding Grafana in an iframe.

To see why authentication is failing, enable debug logging:

[log]
level = debug
filters = auth.jwt:debug

Restart Grafana and check the logs → they should indicate why the JWT was rejected.

@infofcc3 thank you for your response.
Yes I did miss to write JWT step in the question but it was in place using a public private key.

Actually, the issue was with nginx configuration. It seems Grafana queries multiple endpoints at once to authenticate the user (haven’t confirmed this statement yet). I added the following endpoints in nginx and it worked for me:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    map $cookie_jwt_token $jwt_token {
        "" "";
		default $cookie_jwt_token;
    }

    server {
        listen       8080;
        server_name  localhost;

        
        location / {
            root   full/path/to/nginx/html_folder;
            index  index.html;
        }
		
		

        
        location /d/<dashboard_key>/<dashboard_name>{
            proxy_pass http://127.0.0.1:3000/d/<dashboard_key>/<dashboard_name>;
            proxy_set_header Host $host;
			
            proxy_set_header X-JWT-Assertion "$jwt_token";
			
        }


        location /login {
            proxy_pass http://127.0.0.1:3000/login;
            proxy_set_header Host $host;
            proxy_set_header X-JWT-Assertion "$jwt_token";
            #proxy_hide_header X-Frame-Options;
        }

        location /api {
            proxy_pass http://127.0.0.1:3000/api;
            proxy_set_header Host $host;
            proxy_set_header X-JWT-Assertion "$jwt_token";
        }

        location /public {
            proxy_pass http://127.0.0.1:3000/public;
            proxy_set_header Host $host;
        }
    }
}

I hope this helps someone struggling for hours if not days like me :slight_smile:

More about this is present in the following links:

  1. Run Grafana behind a reverse proxy | Grafana Labs