diff --git a/conf/defaults.ini b/conf/defaults.ini index ade66815710..519de55ab3a 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1399,8 +1399,11 @@ plugin_catalog_url = https://grafana.com/grafana/plugins/ plugin_catalog_hidden_plugins = # Log all backend requests for core and external plugins. log_backend_requests = false -# Force download of public key for verifying plugin signature on startup. -enforce_public_key_download = false +# Disable download of the public key for verifying plugin signature. +public_key_retrieval_disabled = false +# Force download of the public key for verifying plugin signature on startup. If disabled, the public key will be retrieved every 10 days. +# Requires public_key_retrieval_disabled to be false to have any effect. +public_key_retrieval_on_startup = false #################################### Grafana Live ########################################## [live] diff --git a/conf/sample.ini b/conf/sample.ini index 911132f720e..8bb0b9d9b53 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -1326,8 +1326,11 @@ ;plugin_catalog_hidden_plugins = # Log all backend requests for core and external plugins. ;log_backend_requests = false -# Force download of public key for verifying plugin signature on startup. -;enforce_public_key_download = false +# Disable download of the public key for verifying plugin signature. +; public_key_retrieval_disabled = false +# Force download of the public key for verifying plugin signature on startup. If disabled, the public key will be retrieved every 10 days. +# Requires public_key_retrieval_disabled to be false to have any effect. +; public_key_retrieval_on_startup = false #################################### Grafana Live ########################################## [live] diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 44b3d5f811e..620d8fb227e 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -2033,6 +2033,14 @@ Custom install/learn more URL for enterprise plugins. Defaults to https://grafan Enter a comma-separated list of plugin identifiers to hide in the plugin catalog. +### public_key_retrieval_disabled + +Disable download of the public key for verifying plugin signature. The default is `false`. If disabled, it will use the hardcoded public key. + +### public_key_retrieval_on_startup + +Force download of the public key for verifying plugin signature on startup. The default is `false`. If disabled, the public key will be retrieved every 10 days. Requires `public_key_retrieval_disabled` to be false to have any effect. +
## [live] diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 1f3f9d12f48..d61fabe78a8 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -108,7 +108,6 @@ Experimental features might be changed or removed without prior notice. | `alertStateHistoryLokiOnly` | Disable Grafana alerts from emitting annotations when a remote Loki instance is available. | | `unifiedRequestLog` | Writes error logs to the request logger | | `pyroscopeFlameGraph` | Changes flame graph to pyroscope one | -| `pluginsAPIManifestKey` | Use grafana.com API to retrieve the public manifest key | | `extraThemes` | Enables extra themes | | `lokiPredefinedOperations` | Adds predefined query operations to Loki query editor | | `pluginsFrontendSandbox` | Enables the plugins frontend sandbox | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index ed48409bb9b..656f35f3260 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -90,7 +90,6 @@ export interface FeatureToggles { refactorVariablesTimeRange?: boolean; useCachingService?: boolean; enableElasticsearchBackendQuerying?: boolean; - pluginsAPIManifestKey?: boolean; advancedDataSourcePicker?: boolean; faroDatasourceSelector?: boolean; enableDatagridEditing?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 7aa8b4c0c88..87881d457fa 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -487,12 +487,6 @@ var ( Stage: FeatureStagePublicPreview, Owner: grafanaObservabilityLogsSquad, }, - { - Name: "pluginsAPIManifestKey", - Description: "Use grafana.com API to retrieve the public manifest key", - Stage: FeatureStageExperimental, - Owner: grafanaPluginsPlatformSquad, - }, { Name: "advancedDataSourcePicker", Description: "Enable a new data source picker with contextual information, recently used order and advanced mode", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index a9cba470996..402eff8fd73 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -71,7 +71,6 @@ externalServiceAuth,experimental,@grafana/grafana-authnz-team,true,false,false,f refactorVariablesTimeRange,preview,@grafana/dashboards-squad,false,false,false,false useCachingService,GA,@grafana/grafana-operator-experience-squad,false,false,true,false enableElasticsearchBackendQuerying,preview,@grafana/observability-logs,false,false,false,false -pluginsAPIManifestKey,experimental,@grafana/plugins-platform-backend,false,false,false,false advancedDataSourcePicker,GA,@grafana/dashboards-squad,false,false,false,true faroDatasourceSelector,preview,@grafana/app-o11y,false,false,false,true enableDatagridEditing,preview,@grafana/grafana-bi-squad,false,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 2ab472b452c..108242217dd 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -295,10 +295,6 @@ const ( // Enable the processing of queries and responses in the Elasticsearch data source through backend FlagEnableElasticsearchBackendQuerying = "enableElasticsearchBackendQuerying" - // FlagPluginsAPIManifestKey - // Use grafana.com API to retrieve the public manifest key - FlagPluginsAPIManifestKey = "pluginsAPIManifestKey" - // FlagAdvancedDataSourcePicker // Enable a new data source picker with contextual information, recently used order and advanced mode FlagAdvancedDataSourcePicker = "advancedDataSourcePicker" diff --git a/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever.go b/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever.go index 17948954fef..0b0be7c6dc9 100644 --- a/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever.go +++ b/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever.go @@ -14,7 +14,6 @@ import ( "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/log" "github.com/grafana/grafana/pkg/plugins/manager/signature/statickey" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" ) @@ -29,9 +28,8 @@ type ManifestKeys struct { } type KeyRetriever struct { - cfg *setting.Cfg - log log.Logger - flags featuremgmt.FeatureToggles + cfg *setting.Cfg + log log.Logger lock sync.Mutex cli http.Client @@ -41,20 +39,19 @@ type KeyRetriever struct { var _ plugins.KeyRetriever = (*KeyRetriever)(nil) -func ProvideService(cfg *setting.Cfg, kv plugins.KeyStore, flags featuremgmt.FeatureToggles) *KeyRetriever { +func ProvideService(cfg *setting.Cfg, kv plugins.KeyStore) *KeyRetriever { kr := &KeyRetriever{ - cfg: cfg, - flags: flags, - log: log.New("plugin.signature.key_retriever"), - cli: makeHttpClient(), - kv: kv, + cfg: cfg, + log: log.New("plugin.signature.key_retriever"), + cli: makeHttpClient(), + kv: kv, } return kr } // IsDisabled disables dynamic retrieval of public keys from the API server. func (kr *KeyRetriever) IsDisabled() bool { - return !kr.flags.IsEnabled(featuremgmt.FlagPluginsAPIManifestKey) + return kr.cfg.PluginSkipPublicKeyDownload } func (kr *KeyRetriever) Run(ctx context.Context) error { diff --git a/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever_test.go b/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever_test.go index f395e61ee00..d0fe7dfeca2 100644 --- a/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever_test.go +++ b/pkg/services/pluginsintegration/keyretriever/dynamic/dynamic_retriever_test.go @@ -9,7 +9,6 @@ import ( "time" "github.com/grafana/grafana/pkg/infra/kvstore" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/pluginsintegration/keystore" "github.com/grafana/grafana/pkg/setting" "github.com/stretchr/testify/require" @@ -47,7 +46,7 @@ func Test_PublicKeyUpdate(t *testing.T) { expectedKey := "fake" s, done := setFakeAPIServer(t, expectedKey, "7e4d0c6a708866e7") cfg.GrafanaComURL = s.URL - v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore()), featuremgmt.WithFeatures(featuremgmt.FlagPluginsAPIManifestKey)) + v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore())) go func() { err := v.Run(context.Background()) require.NoError(t, err) @@ -68,7 +67,7 @@ func Test_PublicKeyUpdate(t *testing.T) { expectedKey := "fake" s, done := setFakeAPIServer(t, expectedKey, "7e4d0c6a708866e7") cfg.GrafanaComURL = s.URL - v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore()), featuremgmt.WithFeatures(featuremgmt.FlagPluginsAPIManifestKey)) + v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore())) go func() { err := v.Run(context.Background()) require.NoError(t, err) @@ -88,7 +87,7 @@ func Test_PublicKeyUpdate(t *testing.T) { expectedKey := "fake" s, done := setFakeAPIServer(t, expectedKey, "other") cfg.GrafanaComURL = s.URL - v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore()), featuremgmt.WithFeatures(featuremgmt.FlagPluginsAPIManifestKey)) + v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore())) go func() { err := v.Run(context.Background()) require.NoError(t, err) @@ -115,7 +114,7 @@ func Test_PublicKeyUpdate(t *testing.T) { expectedKey := "fake" s, done := setFakeAPIServer(t, expectedKey, "7e4d0c6a708866e7") cfg.GrafanaComURL = s.URL - v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore()), featuremgmt.WithFeatures(featuremgmt.FlagPluginsAPIManifestKey)) + v := ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore())) // Simulate an updated key err := v.kv.SetLastUpdated(context.Background()) require.NoError(t, err) diff --git a/pkg/services/pluginsintegration/keyretriever/retriever_test.go b/pkg/services/pluginsintegration/keyretriever/retriever_test.go index 283c688fa71..90a41b6f845 100644 --- a/pkg/services/pluginsintegration/keyretriever/retriever_test.go +++ b/pkg/services/pluginsintegration/keyretriever/retriever_test.go @@ -6,7 +6,6 @@ import ( "github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/plugins/manager/signature/statickey" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/pluginsintegration/keyretriever/dynamic" "github.com/grafana/grafana/pkg/services/pluginsintegration/keystore" "github.com/grafana/grafana/pkg/setting" @@ -16,7 +15,7 @@ import ( func Test_GetPublicKey(t *testing.T) { t.Run("it should return a static key", func(t *testing.T) { cfg := &setting.Cfg{} - kr := ProvideService(dynamic.ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore()), featuremgmt.WithFeatures())) + kr := ProvideService(dynamic.ProvideService(cfg, keystore.ProvideService(kvstore.NewFakeKVStore()))) key, err := kr.GetPublicKey(context.Background(), statickey.GetDefaultKeyID()) require.NoError(t, err) require.Equal(t, statickey.GetDefaultKey(), key) diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 498d0f89df7..2f764a320e1 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -241,6 +241,7 @@ type Cfg struct { PluginAdminEnabled bool PluginAdminExternalManageEnabled bool PluginForcePublicKeyDownload bool + PluginSkipPublicKeyDownload bool PluginsCDNURLTemplate string PluginLogBackendRequests bool diff --git a/pkg/setting/setting_plugins.go b/pkg/setting/setting_plugins.go index 9d95154895d..8eaaf1f8f04 100644 --- a/pkg/setting/setting_plugins.go +++ b/pkg/setting/setting_plugins.go @@ -30,7 +30,8 @@ func (cfg *Cfg) readPluginSettings(iniFile *ini.File) error { cfg.PluginsEnableAlpha = pluginsSection.Key("enable_alpha").MustBool(false) cfg.PluginsAppsSkipVerifyTLS = pluginsSection.Key("app_tls_skip_verify_insecure").MustBool(false) cfg.PluginSettings = extractPluginSettings(iniFile.Sections()) - cfg.PluginForcePublicKeyDownload = pluginsSection.Key("enforce_public_key_download").MustBool(false) + cfg.PluginSkipPublicKeyDownload = pluginsSection.Key("public_key_retrieval_disabled").MustBool(false) + cfg.PluginForcePublicKeyDownload = pluginsSection.Key("public_key_retrieval_on_startup").MustBool(false) pluginsAllowUnsigned := pluginsSection.Key("allow_loading_unsigned_plugins").MustString("")