-
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 
More about this is present in the following links:
- Run Grafana behind a reverse proxy | Grafana Labs