npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@grafana/plugin-validator

v0.20.4

Published

Grafana Plugin Validator

Downloads

555

Readme

Grafana Plugin Validator

License Drone Go Report Card

This tool helps speed up the process of publishing plugins to Grafana.com. It runs a series of analyzers to ensure plugins are following best practices, checking for security and structural issues, as well as specific requirements related to publishing. A general overview of these requirements can be found here: https://grafana.com/docs/grafana/latest/developers/plugins/publishing-and-signing-criteria/.

It requires a path to a remote or local ZIP archive of the plugin to be specified, for example:

  • Remote: https://github.com/grafana/clock-panel/releases/download/v2.1.2/grafana-clock-panel-2.1.2.zip
  • Local: file://Users/me/Downloads/grafana-clock-panel-2.1.2.zip

You can additionally provide a link to the source code for the project with -sourceCodeUri to enable additional analyzers such as the Vulnerability Scan.

Installation and usage

Ensure that your version of Go matches the one specified in the go.mod file to avoid compatibility issues

Docker (recommended)

It is easiest to run the tool using the Docker image as it contains all the security scanning tools needed for the full set of analyzers - so you don't need to have these additional tools installed on your system.

docker run --pull=always grafana/plugin-validator-cli [options] [http://yourdomain/plugin_archive.zip]

Example 1 (basic)

docker run --pull=always grafana/plugin-validator-cli https://github.com/grafana/clock-panel/releases/download/v2.1.2/grafana-clock-panel-2.1.2.zip

Example 2 (specifying source code location)

docker run --pull=always grafana/plugin-validator-cli -sourceCodeUri https://github.com/grafana/clock-panel/tree/v2.1.2 https://github.com/grafana/clock-panel/releases/download/v2.1.2/grafana-clock-panel-2.1.2.zip

Using a local archive file with Docker

To run the tool with a local archive you will need to mount it as a docker volume. Here's an example:

docker run --pull=always -v /path/to/plugin_archive.zip:/archive.zip grafana/plugin-validator-cli /archive.zip

[!NOTE] If using relative paths your path must start with ./

Using a local archive file and local source code

docker run --pull=always -v /path/to/plugin_archive.zip:/archive.zip -v /path/to/source_code:/source_code grafana/plugin-validator-cli -sourceCodeUri file:///source_code /archive.zip

[!NOTE] If using relative paths your path must start with ./

NPX

npx -y @grafana/plugin-validator@latest -sourceCodeUri [options] [path/to/plugin_archive.zip]

Locally

First you must compile and install it:

git clone [email protected]:grafana/plugin-validator.git
cd plugin-validator/pkg/cmd/plugincheck2
go install

Then you can run the utility:

plugincheck2 -sourceCodeUri [source_code_location/] [plugin_archive.zip]

Generating local files For validation

You must create a .zip archive containing the dist/ directory but named as your plugin ID:

PLUGIN_ID=$(grep '"id"' < src/plugin.json | sed -E 's/.*"id" *: *"(.*)".*/\1/')
cp -r dist "${PLUGIN_ID}"
zip -qr "${PLUGIN_ID}.zip" "${PLUGIN_ID}"
npx @grafana/plugin-validator@latest -sourceCodeUri file://. "${PLUGIN_ID}.zip"

You can optionally remove the files that were generated:

rm -r "${PLUGIN_ID}" "${PLUGIN_ID}.zip"

Options

Additional options can be passed to the tool:

❯ plugincheck2 -help
Usage plugincheck2:
  -config string (optional)
        Path to configuration file
  -sourceCodeUri string (optional)
        URI to the source code of the plugin. If set, the source code will be downloaded and analyzed. This can be a ZIP file URL, a URL to git repository or a local file (starting with `file://`)
  -strict (optional)
        If set, plugincheck returns non-zero exit code for warnings
  -checksum string (optional)
        If set, the checksum of the plugin archive will be checked against this value. MD5 and SHA256 are supported.
  -analyzer string (optional)
        If set, only an specific analyzer and it's dependencies will run.
  -severity string (optional)
        If used, it will set the severity of the analyzer (it has the highest priority).

Using a configuration file

You can pass a configuration YAML file to the validator with the -config option. Several configuration examples are available to use here: https://github.com/grafana/plugin-validator/tree/main/config.

Enabling and disabling analyzers via config

If you want to disable an specific check (analyzer) you can define this in your configuration file, adding an analyzers section, and specifying which analyzer or analyzer rules to enable and disable.

For example, disable the version analyzer:

global:
  enabled: true
  jsonOutput: false
  reportAll: false

analyzers:
  version:
    enabled: false

You can also disable specific rules or change their severity level:

global:
  enabled: true
  jsonOutput: false
  reportAll: false

analyzers:
  readme:
    rules:
      missing-readme:
        enabled: true
        severity: warning

Severity levels could be: error, warning, or ok.

Note: Grafana Labs enforces its own configuration for plugins submissions and your own config file can't change these rules.

Source code

You can specify the location of the plugin source code to the validator with the -sourceCodeUri option. Doing so allows for additional analyzers to be run and for a more complete scan.

Supported remote Git services

The following public Git services are supported:

  • GitHub
  • GitLab
  • Bitbucket

Private repositories are not currently supported.

Make sure to include the ref (branch or tag) of the corresponding source code.

For example: you are validating version v2.1.2 and your project is in GitHub. Make sure you create a corresponding tag or branch and use the URL https://github.com/grafana/clock-panel/tree/v2.1.2.

Debug mode

You can run the validator in debug mode to get more information about the running checks and possible errors.

Docker:

docker run --pull=always -e DEBUG=1 grafana/plugin-validator-cli -sourceCodeUri https://github.com/grafana/clock-panel/tree/v2.1.2 https://github.com/grafana/clock-panel/releases/download/v2.1.2/grafana-clock-panel-2.1.2.zip

NPX:

DEBUG=1 npx -y @grafana/plugin-validator@latest -sourceCodeUri https://github.com/grafana/clock-panel/tree/v2.1.2 https://github.com/grafana/clock-panel/releases/download/v2.1.2/grafana-clock-panel-2.1.2.zip

Locally:

DEBUG=1 plugincheck2 -sourceCodeUri https://github.com/grafana/clock-panel/tree/v2.1.2 https://github.com/grafana/clock-panel/releases/download/v2.1.2/grafana-clock-panel-2.1.2.zip

Security tools

This validator makes uses of the following open source security tools:

If you run the validator locally or via NPX you can benefit from installing these tools in your system to make them part of your validation checks.


Analyzers

The tool runs a series of analyzers to ensure submitted plugins are following best practices, and speed up the process of approving a plugin for publishing, detailed in the table below. The Analyzer column includes the name required for altering the behavior of a given check in a configuration file. The Dependencies column specifies whether the analyzer requires the source code for the plugin to be provided with sourceCodeUri or for any additional security scanning tools to be present.

| Analyzer | Description | Dependencies | |----------|-------------|--------------| | Archive Name / archivename | The name of the archive should be correctly formatted. | None | | Archive Structure / archive | Ensures the contents of the zip file have the expected layout. | None | | Backend Binary / backendbinary | Validates the consistency between the existence of a binary file and plugin.json declarations for backend or alerting. | None | | Backend Debug / backenddebug | Checks that the standalone debug files for backend plugins are not present. | None | | Binary Permissions / binarypermissions | For datasources and apps with binaries, this ensures the plugin can run when extracted on a system. | None | | Broken Links / brokenlinks | Detects if any URL doesn't resolve to a valid location. | None | | Checksum / checksum | Validates that the passed checksum (as a validator arg) is the one calculated from the archive file. | checksum | | Circular Dependencies / circulardependencies | Ensures that there aren't any circular dependencies between plugins (plugin.json, dependencies.plugins field). | None | | Code Rules / code-rules | Checks for forbidden access to environment variables, file system or use of syscall module. | semgrep, sourceCodeUri | | Developer Jargon / jargon | Generally discourages use of code jargon in the documentation. | None | | Discoverability / discoverability | Warns about missing keywords and description that are used for plugin indexing in the catalog. | None | | Go Manifest / go-manifest | Validates the build manifest. | None | | Go Security Checker / go-sec | Inspects source code for security problems by scanning the Go AST. | gosec, sourceCodeUri | | JS Source Map / jsMap | Checks for required module.js.map file(s) in archive. | sourceCodeUri | | Legacy Grafana Toolkit usage / legacybuilder | Detects the usage of the not longer supported Grafana Toolkit. | None | | Legacy Platform / legacyplatform | Detects use of Angular which is deprecated. | None | | License Type / license | Checks the declared license is one of: BSD, MIT, Apache 2.0, LGPL3, GPL3, AGPL3. | None | | LLM Review / llmreview | Runs the code through Gemini LLM to check for security issues or disallowed usage. | Gemini API key | | Logos / logos | Detects whether the plugin includes small and large logos to display in the plugin catalog. | None | | Manifest (Signing) / manifest | When a plugin is signed, the zip file will contain a signed MANIFEST.txt file. | None | | Metadata / metadata | Checks that plugin.json exists and is valid. | None | | Metadata Paths / metadatapaths | Ensures all paths are valid and images referenced exist. | None | | Metadata Validity / metadatavalid | Ensures metadata is valid and matches plugin schema. | None | | module.js (exists) / modulejs | All plugins require a module.js to be loaded. | None | | Nested includes metadata / includesnested | Validates that nested plugins have the correct metadata. | None | | Nested Metadata / nestedmetadata | Recursively checks that all plugin.json exist and are valid. | None | | No Tracking Scripts / trackingscripts | Detects if there are any known tracking scripts, which are not allowed. | None | | Organization (exists) / org | Verifies the org specified in the plugin ID exists. | None | | package.json / packagejson | Ensures that package.json exists and the version matches the plugin.json | None | | Plugin Name formatting / pluginname | Validates the plugin ID used conforms to our naming convention. | None | | Published / published-plugin | Detects whether any version of this plugin exists in the Grafana plugin catalog currently. | None | | Readme (exists) / readme | Ensures a README.md file exists within the zip file. | None | | Restrictive Dependency / restrictivedep | Specifies a valid range of Grafana versions that work with this version of the plugin. | None | | Screenshots / screenshots | Screenshots are specified in plugin.json that will be used in the Grafana plugin catalog. | None | | SDK Usage / sdkusage | Ensures that grafana-plugin-sdk-go is up-to-date. | None | | Signature / signature | Ensures the plugin has a valid signature. | None | | Source Code / sourcecode | A comparison is made between the zip file and the source code to ensure what is released matches the repo associated with it. | sourceCodeUri | | Type Suffix (panel/app/datasource) / typesuffix | Ensures the plugin has a valid type specified. | None | | Unique README.md / templatereadme | Ensures the plugin doesn't re-use the template from the create-plugin tool. | None | | Unsafe SVG / manifest | Checks if any svg files are safe based on a whitelist of elements and attributes. | None | | Version / version | Ensures the version submitted is newer than the currently published plugin. If this is a new/unpublished plugin, this is skipped. | None | | Virus Scan / virusscan | Runs a virus scan on the plugin archive and source code using clamscan (clamav). | clamscan | | Vulnerability Scanner / osv-scanner | Detects critical vulnerabilities in Go modules and yarn lock files. | osv-scanner, sourceCodeUri |

Output

By default, the tool outputs results in plain text as shown below.

Default:

warning: README.md: possible broken link: https://www.d3js.org (404 Not Found)
detail: README.md might contain broken links. Check that all links are valid and publicly accessible.
warning: README.md contains developer jargon: (yarn)
detail: Move any developer and contributor documentation to a separate file and link to it from the README.md. For example, CONTRIBUTING.md, DEVELOPMENT.md, etc.
error: osv-scanner detected a critical severity issue
detail: SEVERITY: CRITICAL in package immer, vulnerable to CVE-2021-23436
error: osv-scanner detected a critical severity issue
detail: SEVERITY: CRITICAL in package json-schema, vulnerable to CVE-2021-3918
error: Plugin version 0.0.9 is invalid.
detail: The submitted plugin version 0.0.9 is not greater than the latest published version 0.0.9 on grafana.com.

This can be changed to JSON by passing a configuration file which includes:

global:
  jsonOutput: true

Resulting in output similar to:

{
  "id": "briangann-gauge-panel",
  "version": "0.0.9",
  "plugin-validator": {
    "brokenlinks": [
      {
        "Severity": "warning",
        "Title": "README.md: possible broken link: https://www.d3js.org (404 Not Found)",
        "Detail": "README.md might contain broken links. Check that all links are valid and publicly accessible.",
        "Name": "broken-link"
      }
    ],
    "jargon": [
      {
        "Severity": "warning",
        "Title": "README.md contains developer jargon: (yarn)",
        "Detail": "Move any developer and contributor documentation to a separate file and link to it from the README.md. For example, CONTRIBUTING.md, DEVELOPMENT.md, etc.",
        "Name": "developer-jargon"
      }
    ],
    "osv-scanner": [
      {
        "Severity": "error",
        "Title": "osv-scanner detected a critical severity issue",
        "Detail": "SEVERITY: CRITICAL in package immer, vulnerable to CVE-2021-23436",
        "Name": "osv-scanner-critical-severity-vulnerabilities-detected"
      },
      {
        "Severity": "error",
        "Title": "osv-scanner detected a critical severity issue",
        "Detail": "SEVERITY: CRITICAL in package json-schema, vulnerable to CVE-2021-3918",
        "Name": "osv-scanner-critical-severity-vulnerabilities-detected"
      },
    ],
    "version": [
      {
        "Severity": "error",
        "Title": "Plugin version 0.0.9 is invalid.",
        "Detail": "The submitted plugin version 0.0.9 is not greater than the latest published version 0.0.9 on grafana.com.",
        "Name": "wrong-plugin-version"
      }
    ]
  }
}

Severity

By default, the tool will show any warning or error level results from the analyzers. To see all results including successes, you can pass a configuration file which includes:

global:
  reportAll: true

Getting Help

License

Grafana Plugin Validator is distributed under the Apache 2.0 License.