Why air-gapped Grafana needs a plugin transfer process
Grafana on a network that cannot reach the internet needs a deliberate transfer process for any plugin it does not ship with. In practice, you download plugin ZIP files on a connected host, check them, carry them across the boundary, extract them into the plugin directory or bake them into a custom image, and turn off the outbound update checks and usage reporting that would otherwise fail or stall. Plugins are extensions that add data sources, panels or apps to Grafana. Built-in data sources such as Prometheus and Loki need no plugin, but many community and vendor data sources and panels do. The process is needed when the default install path depends on reaching plugin repositories from the server, which an isolated network blocks. The Grafana installation docs list operating system packages, Docker images and Helm charts, so the offline path is a deliberate choice with its own controls, not a fallback to ignore.
Those controls start with verifying every package before it crosses the boundary. Record each plugin's ID, exact version, license and the Grafana version it targets, and compare the file against the publisher's published checksum or signature where one exists. Many regulated organizations, including utilities subject to NERC CIP-013-2, treat this kind of software integrity and authenticity check as a supply chain control that procurement and change records must show. Licensing also matters: the Grafana licensing page states that plugins keep licenses separate from Grafana's AGPLv3 terms, so the license of each ZIP belongs in the same record as its checksum. Confirm with the plugin publisher whether it accepts offline installation and which dependencies it pulls at runtime, since a plugin that fetches assets from the internet will fail silently on an isolated host.
The transfer process also creates recurring work that teams often underestimate. Every plugin update becomes a new import, test and change request, and the connected host must be kept current enough that the transferred versions stay supported by the Grafana release in use. Decide who owns the staging host, who approves each import, where the approved ZIPs and hashes are stored, and how a rollback is performed if a plugin breaks a dashboard. For Kubernetes or container deployments, the same artifacts can be baked into a custom image, which moves the controls into the image build pipeline. Ask your team to confirm how plugin signature checks are enforced in your Grafana version, and whether unsigned or private plugins will be allowed at all, before the first file is carried over.
Choosing between extracting ZIPs and building a custom image
On a virtual machine or a package-based install, plugins are usually extracted from ZIP archives directly into the Grafana plugin directory on the host. The host's own team owns the work: they stage the archive, check it, copy it across the boundary, extract it and restart the service. Nothing is rebuilt, so the change is small and easy to reverse by replacing the plugin folder with the previous version. The cost is that every node needs the same steps done by hand or by a script, and nothing enforces that the nodes match.
- Maintainer: the team that runs the host, usually platform or operations, owns each extraction and restart.
- Upgrade cadence: each plugin version change is a repeated manual or scripted step on every host, so a checklist or configuration management role is worth keeping.
- Drift risk: a plugin added by hand on one node can be missing from the others, and a provisioning file that lists plugins may not match what is actually on disk.
- Rollback: keeping the previous ZIP and the previous plugin folder lets you restore quickly without a rebuild.
- Provisioning files: the plugin list in your configuration should be updated in the same change as the extraction, or the next restart may behave differently.
Confirm with your own environment how many hosts run Grafana and whether a configuration management tool already applies the same steps to each one.
In container and Kubernetes deployments, plugins are usually either baked into a custom image at build time or mounted into the container from a volume that a separate process has filled. Both approaches make the running state a product of a build or a volume, which is easier to repeat than hand-edited hosts. The trade-off is that the image pipeline or volume process becomes a control point that someone has to own, test and approve.
- Maintainer: the platform team usually owns the image build, while the security or compliance team often reviews what goes into it.
- Upgrade cadence: each plugin change produces a new image tag, which is rolled out through the same process as other releases.
- Drift risk: the image and the provisioning or Helm values can disagree if the plugin list is changed in one place only.
- Rollback: redeploying the previous image tag restores the earlier plugin set, provided the old image is still in your registry.
- Mounted volumes: a shared volume is easier to change but can change without a release, so you need a process that records what was placed on it and when.
Check whether your Grafana image or chart version expects plugins in a specific path, and confirm how your registry will hold images inside the restricted network.
Plugin upgrades are where the two paths differ most in practice. Extraction repeats the same copy and restart steps on each host, so the risk is inconsistency between hosts. Image builds repeat a pipeline that produces an identical artifact, so the risk moves to the pipeline itself: whether it pins versions, verifies checksums and records what it fetched. Either way, the upgrade should be treated as a change with a written record of the plugin name, version, source archive and checksum.
- Version pinning: pin each plugin to an explicit version in the build or the extraction script rather than taking whatever is current when the step runs.
- Integrity checks: record a checksum for every archive when it is downloaded on the connected side and verify it again after transfer.
- Test before promotion: run the upgraded plugin in a non-production instance before the same version reaches production.
- Grafana version fit: plugin versions must match the Grafana release in use, so an upgrade of Grafana itself may require a plugin upgrade in the same window.
- Change record: note who approved each plugin version, which supports supply chain expectations in frameworks that cover software integrity.
Confirm with the plugin's documentation which Grafana versions it supports before you schedule the upgrade.
Drift is the gap between what your configuration says should be installed and what is actually running. Both methods can drift, but they drift in different places. Hand-extracted plugins drift from the provisioning files when someone changes the disk and forgets the configuration, while image-based plugins drift when the image is rebuilt from a different base or the chart values point at an older tag. Knowing where your own process is weakest tells you which checks to add.
- Configuration versus disk: compare the plugin list in your provisioning or Helm values with the plugin directory on each running node or in each running pod.
- Image versus values: confirm that the image tag in the deployment matches the tag your change record names.
- Undeclared plugins: a plugin that exists on disk but is not declared in configuration may be loaded or ignored depending on settings, so review both.
- Restart timing: a plugin change may only take effect after a restart, so a successful copy does not prove the running instance uses it.
- Evidence: keep a dated inventory of installed plugins per environment so auditors can see what ran and when.
Ask your Grafana vendor or the plugin's documentation which settings govern plugin loading and whether unsigned or unlisted plugins are permitted in your edition.
Configuration options and when each fits
This table compares the four ways to get plugins into an air-gapped Grafana: manual extraction, a custom image, provisioning declarations and turning off outbound checks. Read each row for when it fits, what it changes at upgrade time and what you need to confirm in your own environment before relying on it.
| Option | When it fits | What changes on upgrade | What to confirm |
|---|---|---|---|
| Manual ZIP extraction into the plugin directory | Small, fixed plugin sets on a single virtual machine where someone can repeat the copy steps by hand | Plugins sit outside the image, so each Grafana upgrade needs plugin compatibility rechecked and files re-placed | Plugin version matches the target Grafana minor release and the directory your installation actually reads |
| Plugin entries in a custom image build | Containers and Kubernetes clusters where the image is the unit of change and every plugin must be traceable to a build | Plugins are rebuilt into a new image tag, so the upgrade and plugin set move together and are tested as one artifact | Your registry is reachable from the build network and the image build records plugin checksums |
| Provisioning-based plugin declarations | Teams that want plugin state kept in version-controlled files alongside data sources and dashboards | Declarations load at startup, so a missing or incompatible plugin can block a restart after upgrade | Plugin files are already present on the host or in the image, since declarations do not download them offline |
| Disabling update checks in grafana.ini or GF_ variables | Any restricted network where Grafana should not attempt outbound connections at startup or on a schedule | Settings persist across upgrades, but new releases may add outbound calls, so the setting needs rechecking | Exact key names and behavior for your Grafana version in the configuration documentation |
| Disabling usage reporting in grafana.ini or GF_ variables | Air-gapped sites that must keep usage data inside their own boundary and document that choice | Persists across upgrades, but confirm it still applies after each major release | Which reporting features are covered by the setting and whether any remain active |
| Verifying plugins on a connected host before transfer | Every site, because packages crossing an isolated boundary need an integrity record | Each new plugin version repeats the download, checksum and review steps | Your change process records source, version and hash for each ZIP before it is imported |
Setting up a plugin transfer on an isolated Grafana
This sequence moves Grafana plugins from a connected host into an isolated network and proves each one loads without outbound access before production use. Each step ends with a check so the transfer can be repeated and audited.
Inventory plugins and their licenses
On the connected host, list every plugin the dashboards and data sources depend on, with its plugin ID, exact version, publisher and license. Record which plugins are Grafana Labs plugins, which are community plugins and which are internal panels or data sources built for your systems. Confirm each plugin is compatible with the Grafana version the isolated instance will run, since Grafana releases follow a fixed cadence and plugin versions can lag behind. Done when the inventory has one row per plugin, and every row names a version you intend to test against the target Grafana version.
Download and verify plugin archives
Download each plugin as a ZIP archive on the connected host, using only the sources your change process approves. Record a SHA-256 checksum for every file and compare it with the checksum published by the source where one is available. Confirm the archive contains a plugin.json manifest whose ID and version match your inventory. Store the archives and checksums together in a manifest so the transfer can be reviewed later. Done when every archive has a recorded checksum and a matching manifest entry, and any mismatch has been investigated before the file moves on.
Transfer the bundle through the approved path
Move the archives and the manifest across the isolation boundary using the path your security team has approved, such as a controlled media process or a one-way transfer service. Ask your security owner which scanning and approval records the boundary requires, since NERC CIP-013-2 and similar frameworks expect verification of software integrity before anything crosses. On the isolated side, recompute the checksums and compare them with the manifest. Done when the isolated side has a record that every file arrived unchanged.
Install plugins on a test instance
On a non-production Grafana instance in the isolated network, extract each ZIP into the configured plugin directory, normally set by the paths.plugins setting, and keep the ownership and permissions consistent with the service account that runs Grafana. Enable each plugin only if it is required, and set allow_loading_unsigned_plugins only for plugins you have explicitly reviewed and accepted. Restart Grafana and confirm each plugin appears in the plugin catalog with the expected version. Done when the test instance lists every inventoried plugin at its recorded version and no plugin shows a load error.
Confirm plugins load without network access
Block outbound traffic from the test host, or run it in a network segment with no route to the internet, then restart Grafana and watch the startup logs. Confirm each plugin loads and that no log line shows an attempt to fetch plugin catalog data, update checks or usage reports. Check that the dashboards using each plugin render and that data source queries work against internal systems only. Done when the logs show clean plugin loading with no outbound fetch errors, and the test results are saved with the manifest.
Review outbound settings and document the state
Review the Grafana configuration for settings that send usage data, check for updates or contact external services, and set them to the values your isolation policy requires. Record the final configuration file, the plugin manifest and the test results as the baseline for this release. Ask your security owner to confirm that the documented state matches the approved design. Done when the baseline record is signed off and any setting you could not verify is listed as an open item with an owner.
Roll the same bundle to production
Deploy the exact archives and manifest already tested into production through your normal change process, not a fresh download. Repeat the checksum comparison and the plugin list check on each production node, then restart Grafana and review the logs for outbound fetch attempts. If you run more than one Grafana server, confirm every node loads the same plugin versions. Done when each production node reports the same plugin list as the test instance, the logs show no outbound fetches, and the change record links to the baseline.
How Grafana decides whether a plugin is trusted and loadable
Grafana makes two separate decisions about every plugin it finds on disk: whether the plugin is trusted, and whether it is allowed to load. Trust comes from the plugin's signature. Plugins that carry a valid signature load without extra configuration, while a plugin built in-house, or a published ZIP that has been modified, is normally unsigned and fails that check unless you explicitly allow it. The allow-list is the control that matters most for air-gapped work. The allow_loading_unsigned_plugins key in the [plugins] section of grafana.ini, or its GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS environment override, takes plugin IDs, so you can admit one reviewed plugin without admitting every unsigned plugin. Confirm the exact key name and accepted format against the configuration reference for your release.
The plugin directory is where the loader looks, and its location depends on how Grafana was installed. Package and container layouts commonly use /var/lib/grafana/plugins, but confirm the path in your image or package and in the plugins setting before you copy anything. Each plugin sits in its own folder named for its plugin ID and contains a plugin.json manifest, and the Grafana service user must be able to read it. Extracting a ZIP one level too deep, nesting a version folder inside another, or leaving an older copy beside a newer one are common reasons a plugin does not appear after restart. Provisioning is the repeatable part. The Grafana provisioning docs describe loading data sources, dashboards, plugins and alerting resources from YAML or JSON files at startup, so the plugin list can live in version control and be applied to every build instead of being set by hand on each server.
Verify the chain in order on a staging instance before you change production. Start Grafana with the allow-list empty, read the startup log for signature or loading errors, then add only the plugin IDs you have reviewed and restart. Record the SHA-256 checksum of each ZIP on the connected host and check it again after transfer, because the transfer step is where a file can be swapped unnoticed. Keep the allow-list in the same repository as the provisioning files so a reviewer sees every exception. Plan for upgrades as well, since a plugin may need to match the Grafana release it runs on. Confirm the exact log messages and the compatibility rules for your version against the release notes before you rely on them.
Security and operational controls for transferred plugins
Every plugin ZIP that crosses into an isolated network becomes part of your Grafana attack surface, so the transfer needs the same scrutiny as any other software entering the boundary. The cards below cover verification, approval, inventory, plugin trust, outbound behavior and patching, which together decide whether the plugin set stays known and supportable after the first install.
Verify checksums and signatures
Before a plugin ZIP leaves the connected host, record its checksum and check its signature against the publisher's published values. Compare the same values again after the file lands inside the enclave, so a changed file is caught at the boundary rather than at runtime. Keep the hash record with the transfer ticket. Confirm with your Grafana Labs or plugin publisher documentation how each plugin is signed, because signing practice differs between plugins.
Control who approves plugin media
Name a small group that approves each plugin before it is downloaded, separate from the people who download it. The approval record should state the plugin ID, version, publisher, license and the business reason for it. Limit write access to the plugin directory on the target host to the automation or administrators who install approved media, so an unreviewed ZIP cannot be added by hand.
Inventory plugin versions per release
Keep a register that maps each Grafana release in use to the exact plugin versions installed with it. Plugins are versioned separately from Grafana, so a Grafana upgrade can leave a plugin incompatible or unpatched without any visible error. Review the register before every upgrade and record which ZIPs remain in the offline repository so a rollback can reinstall the matching set.
Assess unmaintained and third-party plugins
Plugins from outside Grafana Labs, or those with no recent releases, carry risk that a patched Grafana core does not remove. Check each plugin's maintenance status, source repository, license and the permissions it requests before approval. Plan a replacement or removal path for any plugin that stops receiving fixes, and treat a plugin you cannot rebuild from a known source as a higher-risk item.
Disable outbound checks and reporting
Set the configuration that turns off update checks and anonymous usage reporting so Grafana does not attempt outbound connections from the isolated network. Confirm the exact keys for your Grafana version in the configuration reference, and test them by watching the host's egress logs during a plugin install. A blocked connection that is not visible in the logs is still a failed control.
Patch plugins with Grafana releases
Grafana patch releases arrive at least monthly according to Grafana's upgrade guidance, so plan a repeatable cycle that transfers the matching plugin updates in the same change window. Retest dashboards that depend on each plugin in a staging instance before production. Record the change in the inventory so the security team can show which plugin versions were in use at any date.
Questions teams ask before installing plugins offline
What drives the cost and effort of an offline Grafana plugin install?
The main drivers are how many plugins you need, how many of them have dependencies or native binaries that must match your Grafana version and operating system, and how many Grafana environments must receive the same set. Each plugin adds a download, a checksum or signature check, a copy into the plugin directory or image, and a test on a staging instance. The cost is mostly the time of the people doing that work and the change control around it. Ask any partner to split the quote into discovery, packaging, build pipeline, testing and handover so you can see which components scale with your catalog.
How long does an air-gapped plugin install take for a small set versus a large catalog?
A small, fixed set of plugins on one Grafana instance is mostly a sequence of download, transfer, install and verification steps, so the duration grows with the number of plugins and environments rather than with the platform itself. A large catalog adds version matching against each Grafana release you run, a repeatable build of a custom image, and approval for each package crossing the boundary. This page does not supply a duration figure, so ask for a timeline in the written scope that lists the plugin count, the environments and the approval steps your security team requires.
What does an offline plugin install need from our own team?
You need an owner who can approve packages for transfer, a connected host where downloads happen, and access to the target Grafana hosts or image build system. Someone must also know which Grafana version runs in each environment, because plugin compatibility depends on it. Security reviewers usually need to agree on how each ZIP is checked before it crosses the boundary, which connects to supply chain expectations such as those in NERC CIP-013-2 for verifying software integrity and authenticity where that standard applies. Confirm these responsibilities before work starts so that approvals do not become the critical path.
Can our team install Grafana plugins offline without outside help?
Yes, a capable platform team can do it, and the core steps are straightforward: download the plugin ZIP on a connected host, extract it into the plugin directory, and restart Grafana. The harder parts are repeatability and control. Teams often need a custom image build, a record of which plugin versions each environment runs, and settings that stop outbound update checks and usage reporting so the instance does not try to reach the internet. If your staff already run Grafana in production, the gap is usually the packaging and verification process rather than the Grafana commands themselves. Partner help is most useful when you need that process written down and handed over.
How often do plugins need to be re-transferred into an air-gapped Grafana?
Plugins need re-transfer whenever you upgrade Grafana to a version the plugin does not support, whenever you need a security fix in a plugin, or whenever you want new features. Grafana's upgrade guidance describes major releases once a year in April or May, minor releases every other month and patch releases at least monthly, so the transfer cycle should follow your chosen upgrade cadence. Each cycle repeats the download, check, approval and install steps for every plugin in use, which is why a repeatable process and a pinned plugin list reduce recurring effort.
What should we ask for in a quote for offline Grafana plugins?
Ask for a written scope that lists each plugin, its version, every Grafana environment it targets, and the Grafana version each environment runs. Request the packaging method (manual install, custom image or both), the verification steps for each package, and how outbound update checks and usage reporting will be disabled and tested. Ask which deliverables you receive, such as build scripts, a plugin inventory, runbooks for the next transfer cycle and test evidence. Also ask what is one-time work and what recurs for upgrades, and which items depend on your own approvals or access so you can plan those dates.
Do air-gapped plugin installs affect licensing or support terms?
Plugins carry their own licenses, which can differ from Grafana's AGPLv3 license, so check the license of each plugin before you copy it into a restricted network. Grafana Labs' licensing page notes that plugins, SDKs and agent software kept other licenses after the 2021 change. Also confirm with the plugin vendor whether support covers offline installs, because some support terms assume internet access for updates. Document these checks in the plugin inventory so that auditors and your own teams can see the basis for each package.
How licensing and release changes affect offline plugins
Before any plugin enters an isolated network, check its license separately from Grafana's. On April 20, 2021, Grafana Labs relicensed Grafana, Loki and Tempo from Apache License 2.0 to AGPLv3. The same licensing change left plugins, SDKs and agent software under other licenses, so the Grafana core license does not tell you what a plugin's terms allow. For each plugin on your list, record its license from the plugin's own listing or source repository, confirm whether it permits the way you will redistribute it internally, and keep that record with the ZIP you transfer. Your legal or open-source review team should own this step, and it should happen before the plugin is baked into an image or copied across the boundary.
Grafana also releases often, so a plugin verified against one version can break on the next. The release history includes Grafana 13.1.0 on July 1, 2026, Grafana 13.2.0 on August 18, 2026, and patch releases 13.2.4, 13.1.8 and 13.0.11 on October 13, 2026, according to the grafana/grafana releases page. Because your connected host cannot check compatibility for you at the moment of transfer, treat each Grafana version, including patch releases, as a trigger to recheck every plugin version and its supported Grafana range. Confirm the compatibility statement in each plugin's documentation, then pin the exact plugin version in your build record. The Grafana upgrade guidance describes how often minor and patch releases arrive, which helps you schedule these rechecks.
How DeployOpen scopes and delivers offline Grafana plugin work
DeployOpen plans offline plugin installation as a fixed-scope piece of work inside your own infrastructure, starting from the plugins you actually need and the network rules that govern them. We build the transfer, verification and configuration steps so your team can repeat them for each Grafana upgrade and plugin update.
How we scope
- Inventory every plugin, data source and panel your dashboards and alerts depend on before any download begins.
- Record each plugin's version, license and publisher, and the Grafana version it must match.
- Agree in writing which of the three install paths your environment will use: manual extraction, custom image or a mirrored package repository.
How we build
- Download plugin ZIPs on a connected host, check their checksums, and move them across the boundary under your change control.
- Extract plugins into the configured plugin directory and set ownership so the Grafana service can read them without broader permissions.
- Build a custom image with plugins baked in, and disable update checks and usage reporting in the configuration you hand over.
How we hand over
- Deliver a runbook covering the transfer procedure, verification steps, rollback and the order to follow for each plugin update.
- Test plugin loading, data source connections and dashboard rendering on a staging instance that mirrors your restricted network.
- Document the outbound settings chosen, so your security team can confirm no unexpected egress remains after go-live.
How we support
- Review each Grafana minor and patch release for plugin compatibility before your team schedules the offline update.
- Repeat the transfer and verification steps for new or updated plugins under the same written scope.
- Offer ongoing support and upgrades as a retainer, agreed separately from the fixed-scope implementation.

