Generate shareable, login-free dashboard links authenticated by an API key.
Why use API key sharing
-
Native Grafana supports dashboard sharing only through Snapshots (static, non-updating) or anonymous mode (insecure without IP whitelisting). Managed Service for Grafana supports generating login-free, shareable dashboard links by using API key authentication.
-
You can share these links with other users.
-
Users with the link can access the specified dashboard without logging in, as the API key handles authentication.
-
-
In Grafana 10.0.x and later, API keys are replaced by service account tokens.
Step 1: Configure Grafana parameters
-
Log on to the Managed Service for Grafana console. In the left-side navigation pane, click Workspace Management.
-
On the Workspace Management page, click the ID of the workspace that you want to manage.
-
In the navigation pane on the left, click Parameter Settings.
-
In the parameter list on the left, select aliyun and then click Modify Parameters.
-
Set the runtime parameter for api_key_share to true, and then click Save and Apply.

-
Optional: If you want to use the link for iframe embedding, adjust the following parameters.
-
Cross-domain
The domain must use HTTPS. Modify the following three security parameters.
allow_embedding=true cookie_samesite=none cookie_secure=true
-
Same-domain
In the security section, set the allow_embedding parameter to true to enable iframe embedding.
-
If the iframe is embedded into another Grafana instance, adjust the panels parameters in that Grafana instance.
enable_alpha = true disable_sanitize_html = true
-
Step 2: Create an API key
The steps differ by Grafana version.
If you upgrade from 9.0.x to 10.0.x, existing API keys remain visible on Administration > api keys. Click migrate to service account to migrate them. After migration, the api keys page is hidden. Existing API keys continue to work.
Grafana 9.0.x
-
Log on to the Managed Service for Grafana console. In the left-side navigation pane, click Workspace Management.
-
On the Workspace Management page, find the workspace that you want to manage and click the URL in the URL column to go to Grafana.
NoteYou can log on to Grafana with the administrator account of Grafana and the password that you configured when you created the workspace. You can also click Sign in with Alibaba Cloud to log on to Grafana with the current Alibaba Cloud account.
-
In the upper-left corner of the Grafana homepage, click the
icon. -
In the navigation pane on the left of Grafana, choose Configuration > API keys.
NoteYou must be an Admin to access this menu.
-
Click New API key or Add API key and then configure the following parameters.
Parameter
Description
Key name
A unique name for the API key.
Role
Set the role to Viewer.
Time to live
Set a validity period, such as 60s (60 seconds), 10m (10 minutes), or 1d (1 day).
-
Click Add. In the dialog box that appears, save the API key.
ImportantThe API key is displayed only once. Be sure to save it before you close the dialog box.

Grafana 10.0.x
-
Log on to the Managed Service for Grafana console. In the left-side navigation pane, click Workspace Management.
-
On the Workspace Management page, find the workspace that you want to manage and click the URL in the URL column to go to Grafana.
NoteYou can log on to Grafana with the administrator account of Grafana and the password that you configured when you created the workspace. You can also click Sign in with Alibaba Cloud to log on to Grafana with the current Alibaba Cloud account.
-
In the upper-left corner of the Grafana homepage, click the
icon. -
In the navigation pane on the left of Grafana, choose .
Important-
You must be an Admin to access this menu.
-
Each service account consumes one user slot.
-
-
Click Add service account, configure the following parameters, and then click Create.
Parameter
Description
Display name
A unique name for the service account.
Role
Set the role to Viewer.
-
On the right side of the page, click Add service account token and configure the following parameters.
Parameter
Description
Display name
A unique name for the service account token.
Expiration
Set the validity period.
-
No Expiration: The token does not expire.
-
Set Expiration date: The token is valid until a specific date.
Expiration date
This field is required if you select Set Expiration date.
-
-
Click Generate token, and then click Copy to clipboard and close in the dialog box that appears.
After you close the dialog box, you cannot view the token again.
Step 3: Generate a shareable link
Grafana 9.0.x
-
In Grafana, go to the dashboard that you want to share.
-
Click the
icon and obtain the dashboard share link from the Link tab.
-
Append
&aliyun_api_key=<API key value>to the end of the link. The API key value is the API key that you obtained in Step 2.https://grafana-example.grafana.aliyuncs.com/d/TZWea****/test?orgId=1&from=167081684****&to=167083844****&aliyun_api_key=eyJr****WkIwNnN2c0RTSD****** -
Use the shareable link with the API key to access the Grafana dashboard without logging in.
Grafana 10.0.x
-
In Grafana, go to the dashboard that you want to share.
-
Click the
icon and obtain the dashboard share link from the Link tab. -
Append
&aliyun_api_key=<API key value>to the end of the link. The API key value is the service account token that you obtained in Step 2.https://grafana-example.grafana.aliyuncs.com/d/TZWea****/test?orgId=1&from=167081684****&to=167083844****&aliyun_api_key=eyJrIjoiWkIwNnN2c0RTSD****** -
Use the shareable link with the service account token to access the Grafana dashboard without logging in.
Step 4: Generate a high-security link (Optional)
The sharing link from Step 3: Generate a sharing link exposes the API key directly in the URL, requiring periodic key rotation. This step describes how to generate high-security, time-limited links using PBKDF2 encryption and MD5 signing for version 9.0.x (API keys) and version 10.0.x (service account tokens).
Set the runtime value of the api_key_share_version parameter to v2 before proceeding.
-
Log on to the Managed Service for Grafana console. In the left-side navigation pane, click Workspace Management.
-
On the Workspace Management page, click the ID of the target workspace, and then in the navigation pane on the left, click Parameter Settings.
-
Set the runtime parameter of api_key_share_version to v2 and then click Save and Apply.

API keys (Grafana 9.0.x)
-
Base64-decode the API key that you obtained in Step 2.
Base64 encodes binary data as printable characters for safe transmission.
-
You can use an online tool, such as base64, to decode the API key.
-
Decode in Java.
package main import java.util.Base64; public class Base64Example{ public static void main(String[] args) { String apiKey = "eyJr****REpzZGYzd2JIa0N3ekgyWjlWWmhrSTM5bWdGT2hGSmwiLCJuIjoidGVzdDEiLCJpZCI6MX0="; String decodeKey = new String(Base64.getDecoder().decode(apiKey)); System.out.println(decodeKey); } }Output:
{"k":"DJsd****HkCwzH2Z9VZhkI39mgFOhFJl","n":"test1","id":1} -
Decode in Go.
package main import "fmt" import "encoding/base64" func main() { apiKey := "eyJr****REpzZGYzd2JIa0N3ekgyWjlWWmhrSTM5bWdGT2hGSmwiLCJuIjoidGVzdDEiLCJpZCI6MX0=" decodeKey, err := base64.StdEncoding.DecodeString(apiKey) if err != nil { fmt.Println(err.Error()) return } fmt.Println(string(decodeKey)) }Output:
{"k":"DJsd****HkCwzH2Z9VZhkI39mgFOhFJl","n":"test1","id":1}
-
-
Encrypt the
kvalue from the decoded API key with PBKDF2.PBKDF2 derives an encryption key from a password, a salt, and an iteration count. It makes offline cracking difficult if a database is compromised.
The following table describes the encryption parameters.
Parameter
Description
salt
Set to the API key name, which is the decoded
nvalue. In this example, the value is test1.iterations
Set to 10000.
output len
Set to 50.
key size
Set to 256.
Output type
Set to Hex.
-
You can use an online tool, such as df2, to encrypt the key.
-
Encrypt in Java.
package main import javax.crypto.SecretKeyFactory; import java.security.GeneralSecurityException; import javax.crypto.spec.PBEKeySpec; import java.security.spec.KeySpec; public class PBKDFExapmle { public static void main(String[] args) { String password = "DJsd****HkCwzH2Z9VZhkI39mgFOhFJl"; String salt = "test1"; int iterationCount = 10000; int outputLength = 50 * 8; try { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), iterationCount, outputLength); SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] keyBytes = skf.generateSecret(spec).getEncoded(); System.out.println(bytesToHex(keyBytes)); } catch (GeneralSecurityException e) { e.printStackTrace(); } } private static String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } }Output: PBKDF2 Password
1e5b****80184e78832544aae4d2e031a3539c10b575b75d7c1d44af49fcf5a7de9c58a5f0035ce35fff0e5b0476e882**** -
Encrypt in Go.
package main import "fmt" import "encoding/hex" import "crypto/sha256" import "golang.org/x/crypto/pbkdf2" func main() { password:="DJsd****HkCwzH2Z9VZhkI39mgFOhFJl" salt="test1" newPasswd := pbkdf2.Key([]byte(password), []byte(salt), 10000, 50, sha256.New) encodePassword:= hex.EncodeToString(newPasswd) fmt.Println(encodePassword) }Output: PBKDF2 Password
1e5b****80184e78832544aae4d2e031a3539c10b575b75d7c1d44af49fcf5a7de9c58a5f0035ce35fff0e5b0476e882****
-
-
Construct the MD5 digest signature parameter from the PBKDF2-encrypted information.
The MD5 digest algorithm is a cryptographic hash function that produces a 128-bit hash value to verify data integrity.
Content to be encrypted: <PBKDF2 Password>+"_"+<Current system time as an integer in seconds>
Example:
PBKDF2 Password: 1e5b****80184e78832544aae4d2e031a3539c10b575b75d7c1d44af49fcf5a7de9c58a5f0035ce35fff0e5b0476e882****
Current system time: 2024-09-20 17:12:13, which is 1726823533 in seconds.
The complete information to be signed with MD5: 1e5b****80184e78832544aae4d2e031a3539c10b575b75d7c1d44af49fcf5a7de9c58a5f0035ce35fff0e5b0476e882****_1726823533
You can create an MD5 signature in several ways:
-
Use an online tool, such as MD5, to perform the encryption.
-
Perform MD5 signing by using Java code.
package main; import java.security.MessageDigest; public class MD5 { public static void main(String[] args) { String pbkdfPassword = "1e5b****80184e78832544aae4d2e031a3539c10b575b75d7c1d44af49fcf5a7de9c58a5f0035ce35fff0e5b0476e882****"; long timeSeconds=System.currentTimeMillis()/1000; String key=pbkdfPassword+"_"+timeSeconds; System.out.println(MD5.getMD5String(key,"UTF-8")); } public static String getMD5String(String str, String charset) { try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(str.getBytes(charset)); byte[] byteArray = messageDigest.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < byteArray.length; i++) { if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) { md5StrBuff.append("0").append( Integer.toHexString(0xFF & byteArray[i])); } else { md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); } } return md5StrBuff.toString().toLowerCase(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("MD5 error:"+e.getMessage()); } } } -
Perform MD5 signing by using Go code.
package main import ( "crypto/md5" "encoding/hex" "fmt" "io" "time" "strconv" ) func main() { // String to calculate MD5 for pbkdfPassword := "1e5b****80184e78832544aae4d2e031a3539c10b575b75d7c1d44af49fcf5a7de9c58a5f0035ce35fff0e5b0476e882****" timeSeconds:= time.Now().Unix() key:=pbkdfPassword+"_"+strconv.FormatInt(timeSeconds, 10) // Calculate the MD5 of the string hash := md5.New() io.WriteString(hash, key) md5Str := hash.Sum(nil) // Convert the binary MD5 value to a hexadecimal string md5StrHex := hex.EncodeToString(md5Str) fmt.Println("MD5 of", key, "is", md5StrHex) }
-
-
Append parameters to the link based on the generated MD5 signature.
Parameter description:
Parameter
Description
Example
aliyun_api_key_sign
The MD5 signature, which changes over time.
c3bf89b867cc88df72d507edc4d1****
aliyun_api_key_timestamp
The signature timestamp. The signature expires if the difference between the signature time and the server time exceeds one minute.
1726823533
aliyun_api_key_name
The name of the API key.
test1
aliyun_api_key_org_id
The organization ID of the API key.
1
aliyun_api_key_expire_seconds
The duration in seconds for which the session remains valid after login.
Default: 3600
Example:
https://grafana-example.grafana.aliyuncs.com/d/TZWea****/test?orgId=1&from=167081684****&to=167083844****&aliyun_api_key_sign=c3bf89b867cc88df72d507edc4d1****&aliyun_api_key_timestamp=1726823533&aliyun_api_key_name=test1&aliyun_api_key_org_id=1You can now programmatically generate secure, login-free links to Grafana without exposing the long-lived API key.
Service account tokens (Grafana 10.0.x)
-
Split the service account token from Step 2 and then encrypt its secret portion using PBKDF2.
PBKDF2 derives an encryption key from a password, a salt, and an iteration count. It makes offline cracking difficult if a database is compromised.
Split the service account token by the underscore character (_).
# Example service account token: Token:glsa_yV9HAOVCjNKkvKoLMiypOc5T0Oov****_4f5ff3ce # After splitting: Prefix:glsa Secret:yV9HAOVCjNKkvKoLMiypOc5T0Oov**** Salt:4f5ff3ceThe following table describes the encryption parameters.
Parameter
Description
salt
Set to the token suffix. In this example, the value is 4f5ff3ce.
iterations
Set to 10000.
output len
Set to 50.
key size
Set to 256.
Output type
Set to Hex.
-
You can use an online tool, such as charsetpbkdf2, to encrypt the key.
-
Encrypt in Java.
package main import javax.crypto.SecretKeyFactory; import java.security.GeneralSecurityException; import javax.crypto.spec.PBEKeySpec; import java.security.spec.KeySpec; public class PBKDFExapmle { public static void main(String[] args) { String password = "yV9H****jNKkvKoLMiypOc5T0OovHXPV"; String salt = "4f5ff3ce"; int iterationCount = 10000; int outputLength = 50 * 8; try { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), iterationCount, outputLength); SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] keyBytes = skf.generateSecret(spec).getEncoded(); System.out.println(bytesToHex(keyBytes)); } catch (GeneralSecurityException e) { e.printStackTrace(); } } private static String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } }Output: PBKDF2 Password
c3cd****971bab928e4ecd6e7a00c74657696ea07d38c43f3bb5dc3190f2285cb80695cf7bf2f25c9b1f34fe1e0f9549**** -
Encrypt in Go.
package main import "fmt" import "encoding/hex" import "crypto/sha256" import "golang.org/x/crypto/pbkdf2" func main() { password:="yV9H****jNKkvKoLMiypOc5T0OovHXPV" salt:="4f5ff3ce" newPasswd := pbkdf2.Key([]byte(password), []byte(salt), 10000, 50, sha256.New) encodePassword:= hex.EncodeToString(newPasswd) fmt.Println(encodePassword) }Output: PBKDF2 Password
c3cd****971bab928e4ecd6e7a00c74657696ea07d38c43f3bb5dc3190f2285cb80695cf7bf2f25c9b1f34fe1e0f9549****
-
-
Construct the MD5 digest signature parameter from the PBKDF2-encrypted information.
The MD5 digest algorithm is a cryptographic hash function that produces a 128-bit hash value to verify data integrity.
Content to be encrypted: <PBKDF2 Password>+"_"+<Current system time as an integer in seconds>
Example:
PBKDF2 Password: c3cd****971bab928e4ecd6e7a00c74657696ea07d38c43f3bb5dc3190f2285cb80695cf7bf2f25c9b1f34fe1e0f9549****
Current system time: 2024-09-20 17:12:13, which is 1726823533 in seconds.
The complete information to be signed with MD5: c3cd****971bab928e4ecd6e7a00c74657696ea07d38c43f3bb5dc3190f2285cb80695cf7bf2f25c9b1f34fe1e0f9549****_1726823533
You can create an MD5 signature in several ways:
-
Use an online tool, such as MD5, to perform the encryption.
-
Perform MD5 signing by using Java code.
package main; import java.security.MessageDigest; public class MD5 { public static void main(String[] args) { String pbkdfPassword = "c3cd****971bab928e4ecd6e7a00c74657696ea07d38c43f3bb5dc3190f2285cb80695cf7bf2f25c9b1f34fe1e0f9549****"; long timeSeconds=System.currentTimeMillis()/1000; String key=pbkdfPassword+"_"+timeSeconds; System.out.println(MD5.getMD5String(key,"UTF-8")); } public static String getMD5String(String str, String charset) { try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(str.getBytes(charset)); byte[] byteArray = messageDigest.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < byteArray.length; i++) { if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) { md5StrBuff.append("0").append( Integer.toHexString(0xFF & byteArray[i])); } else { md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); } } return md5StrBuff.toString().toLowerCase(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("MD5 error:"+e.getMessage()); } } } -
Perform MD5 signing by using Go code.
package main import ( "crypto/md5" "encoding/hex" "fmt" "io" "time" "strconv" ) func main() { // String to calculate MD5 for pbkdfPassword := "c3cd****971bab928e4ecd6e7a00c74657696ea07d38c43f3bb5dc3190f2285cb80695cf7bf2f25c9b1f34fe1e0f9549****" timeSeconds:= time.Now().Unix() key:=pbkdfPassword+"_"+strconv.FormatInt(timeSeconds, 10) // Calculate the MD5 of the string hash := md5.New() io.WriteString(hash, key) md5Str := hash.Sum(nil) // Convert the binary MD5 value to a hexadecimal string md5StrHex := hex.EncodeToString(md5Str) fmt.Println("MD5 of", key, "is", md5StrHex) }
-
-
Append parameters to the link based on the generated MD5 signature.
Parameter description:
Parameter
Description
Example
aliyun_api_key_sign
The MD5 signature, which changes over time.
c3bf89b867cc88df72d507edc4d1****
aliyun_api_key_timestamp
The signature timestamp. The signature expires if the difference between the signature time and the server time exceeds one minute.
1726823533
aliyun_api_key_name
The name of the service account token.
sa-1-******-*******-75c7-41ae-94da-*********
aliyun_api_key_org_id
The organization ID of the service account token.
1
aliyun_api_key_expire_seconds
The duration in seconds for which the session remains valid after login.
Default: 3600
Example:
https://grafana-example.grafana.aliyuncs.com/d/TZWea****/test?orgId=1&from=167081684****&to=167083844****&aliyun_api_key_sign=c3bf89b867cc88df72d507edc4d1****&aliyun_api_key_timestamp=1726823533&aliyun_api_key_name=sa-1-******-*******-75c7-41ae-94da-*********&aliyun_api_key_org_id=1You can now programmatically generate more secure, passwordless links to Grafana, which helps prevent exposing the long-lived service account token.
FAQ
-
Why do I see an error when I access a dashboard by using a shared link?

Possible cause: The allow_embedding parameter is not configured. Configure allow_embedding as described in Step 1.
-
Why does the dashboard data fail to display?

When you embed a dashboard, a cookie may fail to be written for the following reasons:
-
Cross-domain access: If the root domains are different, a cookie cannot be written with the default configuration.
-
The cookie_samesite parameter is set to none, but the cookie_secure parameter is set to false.
-
The domain uses HTTP. The cookie_secure parameter does not take effect over HTTP.
Solution: Reconfigure Grafana parameters as described in Step 1.
-
-
Why do I see an error when I access a dashboard by using a shared link?

Possible causes:
-
Your browser version is outdated.
-
A browser setting is causing an issue with the embedded dashboard.
Solution:
-
Check your cookie settings and make sure that cookies are allowed.
-
If you use Google Chrome, you must allow all cookies in Incognito mode.
-
-
-
For embedded dashboards, should I use a short-lived API key or a long-lived one?
Configure the validity period based on your security requirements. Rotate the key every three months. If a key is leaked, delete it to revoke access.
-
Is there a limit on the number of API keys?
Grafana does not limit the number of API keys, but the UI displays a maximum of 100 keys at a time.
-
Is an API key automatically deleted after it expires?
No. Expired keys remain in the system but become invalid. To view and delete them, click Include expired keys.
