mirror of
https://github.com/grafana/grafana.git
synced 2026-07-29 15:59:50 -05:00
Docs: Plugin signing docs (#28671)
* WIP * Update plugin signing docs * Fix review comments
This commit is contained in:
@@ -44,7 +44,7 @@ Use app plugins when you want to create an custom out-of-the-box monitoring expe
|
||||
## Learn more
|
||||
|
||||
- [Install plugins]({{< relref "./installation.md" >}})
|
||||
- [Plugin signature verification]({{< relref "./plugin-signature-verification.md" >}})
|
||||
- [Plugin signatures]({{< relref "./plugin-signatures.md" >}})
|
||||
- Browse the available [Plugins](https://grafana.com/grafana/plugins)
|
||||
|
||||
<!-- BEGIN Optimal Workshop Intercept Snippet --><div id='owInviteSnippet' style='position:fixed;right:20px;bottom:20px;width:280px;padding:20px;margin:0;border-radius:6px;background:#1857B8;color:#F7F8FA;text-align:left;z-index:2200000000;opacity:0;transition:opacity 500ms;-webkit-transition:opacity 500ms;display:none;'><div id='owInviteMessage' style='padding:0;margin:0 0 20px 0;font-size:16px;'>Got a spare two and a half minutes to help us improve the docs?</div><a id='owInviteOk' href='https://Grafana.optimalworkshop.com/questions/grafana-docs?tag=docs&utm_medium=intercept' onclick='this.parentNode.style.display="none";' target='_blank' style='color:#F7FAFF;font-size:16px;font-weight:bold;text-decoration:underline;'>Yes, I'll help</a><a id='owInviteCancel' href='javascript:void(0)' onclick='this.parentNode.style.display="none";' style='color:#F7F8FA;font-size:14px;text-decoration:underline;float:right;'>Close</a></div><script>var owOnload=function(){if(-1==document.cookie.indexOf('ow-intercept-quiz-4ior230e')){var o=new XMLHttpRequest;o.onloadend=function(){try{var o=document.getElementById('owInviteSnippet');var date=new Date();date.setMonth(date.getMonth()+1);this.response&&JSON.parse(this.response).active===!0&&(document.cookie='ow-intercept-quiz-4ior230e=Done;path=/;expires='+date.toUTCString()+';',setTimeout(function(){o.style.display='block',o.style.opacity=1},2e3))}catch(e){}},o.open('POST','https://app.optimalworkshop.com/survey_status/questions/4ior230e/active'),o.send()}};if(window.addEventListener){window.addEventListener('load',function(){owOnload();});}else if(window.attachEvent){window.attachEvent('onload',function(){owOnload();});}</script><!-- END Optimal Workshop snippet -->
|
||||
<!-- BEGIN Optimal Workshop Intercept Snippet --><div id='owInviteSnippet' style='position:fixed;right:20px;bottom:20px;width:280px;padding:20px;margin:0;border-radius:6px;background:#1857B8;color:#F7F8FA;text-align:left;z-index:2200000000;opacity:0;transition:opacity 500ms;-webkit-transition:opacity 500ms;display:none;'><div id='owInviteMessage' style='padding:0;margin:0 0 20px 0;font-size:16px;'>Got a spare two and a half minutes to help us improve the docs?</div><a id='owInviteOk' href='https://Grafana.optimalworkshop.com/questions/grafana-docs?tag=docs&utm_medium=intercept' onclick='this.parentNode.style.display="none";' target='_blank' style='color:#F7FAFF;font-size:16px;font-weight:bold;text-decoration:underline;'>Yes, I'll help</a><a id='owInviteCancel' href='javascript:void(0)' onclick='this.parentNode.style.display="none";' style='color:#F7F8FA;font-size:14px;text-decoration:underline;float:right;'>Close</a></div><script>var owOnload=function(){if(-1==document.cookie.indexOf('ow-intercept-quiz-4ior230e')){var o=new XMLHttpRequest;o.onloadend=function(){try{var o=document.getElementById('owInviteSnippet');var date=new Date();date.setMonth(date.getMonth()+1);this.response&&JSON.parse(this.response).active===!0&&(document.cookie='ow-intercept-quiz-4ior230e=Done;path=/;expires='+date.toUTCString()+';',setTimeout(function(){o.style.display='block',o.style.opacity=1},2e3))}catch(e){}},o.open('POST','https://app.optimalworkshop.com/survey_status/questions/4ior230e/active'),o.send()}};if(window.addEventListener){window.addEventListener('load',function(){owOnload();});}else if(window.attachEvent){window.attachEvent('onload',function(){owOnload();});}</script><!-- END Optimal Workshop snippet -->
|
||||
|
||||
@@ -25,3 +25,11 @@ Grafana Cloud handles the plugin installation automatically.
|
||||
Follow the instructions on the Install tab. You can either install the plugin with a Grafana CLI command or by downloading and uncompress a .zip file into the Grafana plugins directory. We recommend using Grafana CLI in most instances. The .zip option is available if your Grafana server does not have access to the internet.
|
||||
|
||||
For more information about Grafana CLI plugin commands, refer to [Plugin commands]({{< relref "../administration/cli.md#plugins-commands" >}}).
|
||||
|
||||
### Install a packaged plugin
|
||||
|
||||
After the user has downloaded the archive containing the plugin assets, they can install it by extracting the archive into their plugin directory.
|
||||
|
||||
```
|
||||
unzip my-plugin-0.2.0.zip -d YOUR_PLUGIN_DIR/my-plugin
|
||||
```
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
+++
|
||||
title = "Plugin signature verification"
|
||||
type = "docs"
|
||||
+++
|
||||
|
||||
# Plugin signature verification
|
||||
|
||||
Plugin signature verification (signing) is a security measure to make sure plugins haven't been tampered with. Upon loading, Grafana checks to see if a plugin is signed or unsigned when inspecting and verifying its digital signature.
|
||||
|
||||
## How it works
|
||||
|
||||
For Grafana to verify the digital signature of a plugin, the plugin must include a signed manifest file, _MANIFEST.txt_. The signed manifest file contains two sections:
|
||||
|
||||
- **Signed message -** The signed message contains plugin metadata and plugin files with their respective checksums (SHA256).
|
||||
- **Digital signature -** The digital signature is created by encrypting the signed message using a private key. Grafana has a public key built-in that can be used to verify that the digital signature have been encrypted using expected private key.
|
||||
|
||||
### Signed manifest example file
|
||||
|
||||
```txt
|
||||
// MANIFEST.txt
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA512
|
||||
|
||||
{
|
||||
"plugin": "grafana-test-plugin",
|
||||
"version": "1.0.0",
|
||||
"files": {
|
||||
"LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
|
||||
"README.md": "5bfefcdce6eafce3388d1fb200f3b10954cfeac6c7a45fd7dec42687e01ac75d",
|
||||
"module.js": "3c07596a6a4796c65ef10ba2bc0805e7f3bc9e4e8fc9970a1307b97e29db1c0a",
|
||||
"module.js.LICENSE.txt": "fdbc28c10f3d21976b4bc16464ad7c630538c0c3101347b5fd44af9066f7022b",
|
||||
"module.js.map": "c3ac1e8aa98d83c54fd13e43b65e1cf4182a924d2eb23a2f1a6fe40b7785a1bb",
|
||||
"plugin.json": "cf26a3afb7c10cd9ae40b5296d04172b5dac927d69a51082e6d085b34341ccc3"
|
||||
},
|
||||
"time": 1589558058070,
|
||||
"keyId": "7e4d0c6a708866e7"
|
||||
}
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: OpenPGP.js v4.10.1
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
wqAEARMKAAYFAl6+uyoACgkQfk0ManCIZuc0+QIHdWC0dp7GRRFu3Hgk9tnl
|
||||
FJnPwM6Y2tTdq7AkpVTTAb3RTFadA8dRmLfajxgHxmDf5yUv9M2M6sa1eTSG
|
||||
8kJtOlwCB096dXOKsH1IOGQMCY+/xM2081FqbMTvWgN81xrxMoxftQn8z6VC
|
||||
2nA2Rmt1VStppFVCCUXaq6Y4sFGHQF/yq5oi
|
||||
=vqUQ
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
```
|
||||
|
||||
## Plugin signatures
|
||||
|
||||
When Grafana starts, it discovers plugins to load. For each discovered plugin it verifies the authenticity of it, and then decides whether to load it or not based on the state of the plugin signature:
|
||||
|
||||
| Plugin signature | Description |
|
||||
| ---------------- | ----------- |
|
||||
| internal | Core plugin built into Grafana. |
|
||||
| invalid | Digital signature of _MANIFEST.txt_ file is not valid. |
|
||||
| modified | Manifest plugin id or version have been changed or files checksums doesn't match. |
|
||||
| unsigned | Plugin don't have a _MANIFEST.txt_ file. |
|
||||
| valid | If any of the above descriptions is false. |
|
||||
|
||||
The plugin signature state can be inspected for each plugin in the plugins listing page (Configuration -> Plugins).
|
||||
|
||||
## Backend plugins
|
||||
|
||||
If a [backend plugin]({{< relref "../developers/plugins/backend/_index.md" >}}) is not signed, then Grafana will not load or start it. If you try to load a backend plugin with an invalid signature, then Grafana writes an error message to the server log:
|
||||
|
||||
```bash
|
||||
EROR[06-01|16:45:59] Failed to load plugin error=plugin <plugin id> is unsigned
|
||||
```
|
||||
|
||||
> **Note:** All Grafana Labs authored backend plugins, including Enterprise plugins, are signed.
|
||||
|
||||
## Allow unsigned plugins
|
||||
|
||||
While you can allow unsigned plugins using a configuration setting, we strongly advise you not to. For more information on how to allow unsigned backend plugin, refer to [Configuration]({{< relref "../administration/configuration.md#allow-loading-unsigned-plugins" >}}). Allowing unsigned plugins will not skip verifying the authenticity of a plugin if plugin has a _MANIFEST.txt_ file.
|
||||
|
||||
If you run an unsigned backend plugin, then Grafana writes a warning message to the server log:
|
||||
|
||||
```bash
|
||||
WARN[06-01|16:45:59] Running an unsigned backend plugin pluginID=<plugin id>
|
||||
```
|
||||
|
||||
If you're developing plugins and run Grafana from source, the development mode is enabled by default and also allow you to run unsigned backend plugins.
|
||||
@@ -0,0 +1,53 @@
|
||||
+++
|
||||
title = "Plugin signatures"
|
||||
type = "docs"
|
||||
aliases = ["/docs/plugins/plugin-signature-verification"]
|
||||
+++
|
||||
|
||||
# Plugin signatures
|
||||
|
||||
Plugin signature verification (signing) is a security measure to make sure plugins haven't been tampered with. Upon loading, Grafana checks to see if a plugin is signed or unsigned when inspecting and verifying its digital signature.
|
||||
|
||||
At startup, Grafana verifies the signatures of every plugin in the plugin directory. You can see the result of this verification for each plugin by navigating to **Configuration** -> **Plugins**.
|
||||
|
||||
> **Note:** If you're a plugin developer and want to know how to sign your plugin, refer to [Sign a plugin]({{< relref "../developers/plugins/sign-a-plugin.md" >}}).
|
||||
|
||||
| Signature status | Description |
|
||||
| ---------------- | ----------- |
|
||||
| Core | Core plugin built into Grafana. |
|
||||
| Invalid signature | The plugin has a invalid signature. |
|
||||
| Modified signature | The plugin has changed since it was signed. This may indicate malicious intent. |
|
||||
| Unsigned | The plugin is not signed. |
|
||||
| Signed | The plugin signature was successfully verified. |
|
||||
|
||||
## Plugin signature levels
|
||||
|
||||
All plugins is signed under a _signature level_. The signature level determines how the plugin can be distributed.
|
||||
|
||||
|**Plugin Level**|**Description**|
|
||||
|---|---|
|
||||
|Private|<p>Private plugins are for use on your own Grafana. They may not be distributed to the Grafana community, and are not published in the Grafana catalog.</p>|
|
||||
|Community|<p>Community plugins have dependent technologies that are open source and not for profit.</p><p>Community plugins are published in the official Grafana catalog, and are available to the Grafana community.</p>|
|
||||
|Commercial|<p>Commercial plugins have dependent technologies that are closed source or commercially backed.</p><p>Commercial Plugins are published on the official Grafana catalog, and are available to the Grafana community.</p>|
|
||||
|
||||
## Backend plugins
|
||||
|
||||
If a [backend plugin]({{< relref "../developers/plugins/backend/_index.md" >}}) is unsigned, then Grafana won't load or start it. If you try to load a backend plugin with an missing or invalid signature, then Grafana writes an error message to the server log:
|
||||
|
||||
```bash
|
||||
EROR[06-01|16:45:59] Failed to load plugin error=plugin <plugin id> is unsigned
|
||||
```
|
||||
|
||||
> **Note:** All Grafana Labs authored backend plugins, including Enterprise plugins, are signed.
|
||||
|
||||
## Allow unsigned plugins
|
||||
|
||||
We strongly recommend that you don't run unsigned plugins in your Grafana installation. If you're aware of the risks and you still want to load an unsigned plugin, refer to [Configuration]({{< relref "../administration/configuration.md#allow-loading-unsigned-plugins" >}}).
|
||||
|
||||
If you've allowed loading of an unsigned backend plugin, then Grafana writes a warning message to the server log:
|
||||
|
||||
```bash
|
||||
WARN[06-01|16:45:59] Running an unsigned backend plugin pluginID=<plugin id>
|
||||
```
|
||||
|
||||
> **Note:** If you're developing a plugin, then you can enable development mode to allow all unsigned plugins.
|
||||
Reference in New Issue
Block a user