This guide requires you to have a permission to mount/modify the Grafana configuration files (grafana.ini)
Generate RS256 key pair using openssl
a. Run the following commands in terminal, make sure openssl is installed
1openssl genpkey -algorithm RSA -out private.key
2openssl rsa -pubout -in private.key -out public.key
b. These commands will generate 2 files, private.key and public.key
1├── private.key
2└── public.key
Convert the contents of public.key file to JSON format using https://russelldavies.github.io/jwk-creator/
a. Copy the contents of public.key into the PEM encoded key field
b. Fill in the Key ID with grafana
c. Leave the Public Key Use and Algorithm fields empty
d. Click the Convert button
Create a jwks.json file
a. Create a new file named jwks.json and fill it with the following JSON
1{
2 "keys": []
3}
b. Copy the JWK result from https://russelldavies.github.io/jwk-creator/ into the keys array in the jwks.json file. For example:
1{
2 "keys": [
3 {
4 "kty": "RSA",
5 "n": "mCE7VaNgkjT0EyiMhyybdOfMaMWbdGyFhmWr-2e4cHY3oVxsLpdT9rcqPUtpGUI9KpRB-V8fcJj8W8YxpTLEFdca-wDP3Vgdyq76-tNYLicMCuvqQD-2PIHDgzPvGBdbj7SZLKs9v8XUfyJ5MhdeSsQVHczgun34h7BfMPhW_qZwd7mXmXB0NHNRVUSYEpBJFmnp6i6CAF5hIRCCxaFZLdzArWg1WXADDJqTC_nVlKMZkpOLTFP5JqtOrWKJGn-uYINyJ0HreXMSehknCZNh1-S7-J8LG--YL2E4JtwkdbbSA-iyuQYRJUT9WezrS-kQSXypntrC-aAH0YOFj9lw8Q",
6 "e": "AQAB",
7 "kid": "grafana"
8 }
9 ]
10}
c. Save the jwks.json file
Mount jwks.json to /etc/grafana/jwks.json in the Grafana container
Configure Grafana in the grafana.ini file in the Grafana container
1[security]
2allow_embedding = true
3...
4
5[auth.jwt]
6enabled = true
7url_login = true
8header_name = X-JWT-Assertion
9email_claim = sub
10username_claim = user
11jwk_set_file = /etc/grafana/jwks.json
Restart the Grafana container
To access Grafana using JWT, an auth_token needs to be generated first.
auth_token using Python 1import jwt
2import datetime
3
4# Replace with your actual `private.key` content
5SECRET_KEY = f"""-----BEGIN PRIVATE KEY-----
6MIIEvQIBADANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ...
7-----END PRIVATE KEY-----
8"""
9
10payload = {
11 "exp": int((datetime.datetime.now() + datetime.timedelta(hours=50)).timestamp()), # token expiration time (unix timestamp)
12 'sub': 'admin@gmail.com', # grafana user email
13 'user': 'admin', # grafana username
14}
15
16token = jwt.encode(payload, SECRET_KEY, algorithm='RS256', headers={
17 'kid': 'grafana' # use the same key_id (kid) as in jwks.json
18})
19
20token = token.decode('utf-8')
21
22print(f'auth_token: {token}')
auth_token parameter to the Grafana URL. 1from flask_restx import Resource
2from flask import render_template_string
3
4class ApiClass(Resource):
5 def get(self):
6 iframe = 'http://localhost:3000/d-solo/a5919b27-0868-44a0-9f4e-28fad226288f/new-dashboard?orgId=1&panelId=1&auth_token=' + token
7
8 template = f"""
9 <iframe
10 frameborder="0"
11 noresize="noresize"
12 style="position: absolute; background: transparent; width: 100%; height: 100%"
13 src="{ iframe }"
14 frameborder="0"
15 ></iframe>
16 """
17
18 return Response(render_template_string(template), mimetype='text/html')