mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Encryption: Extend secrets service to support registering key providers (#40626)
* Draft adding kms providers * Rename defaultProvider to currentProvider * Add getting current provider from config * Remove comments * Make current provider service struct field * Add methods to secrets service * Test getting current provider * Implements missing methods for fake secrets service * Remove accidental changes * Fix linter issue * Update configuration examples * Rename CurrentProvider method * Split service interface * Update wire Co-authored-by: spinillos <selenepinillos@gmail.com>
This commit is contained in:
parent
9f205cf1d7
commit
e81d434edf
@ -228,6 +228,9 @@ admin_password = admin
|
||||
# used for signing
|
||||
secret_key = SW2YcwTIb9zpOOhoPsMm
|
||||
|
||||
# key provider used for envelope encryption, default to static value specified by secret_key
|
||||
encryption_provider = secretKey
|
||||
|
||||
# disable gravatar profile images
|
||||
disable_gravatar = false
|
||||
|
||||
|
@ -222,6 +222,9 @@
|
||||
# used for signing
|
||||
;secret_key = SW2YcwTIb9zpOOhoPsMm
|
||||
|
||||
# key provider used for envelope encryption, default to static value specified by secret_key
|
||||
;encryption_provider = secretKey
|
||||
|
||||
# disable gravatar profile images
|
||||
;disable_gravatar = false
|
||||
|
||||
|
@ -156,6 +156,7 @@ var wireBasicSet = wire.NewSet(
|
||||
elasticsearch.ProvideService,
|
||||
secretsManager.ProvideSecretsService,
|
||||
wire.Bind(new(secrets.Service), new(*secretsManager.SecretsService)),
|
||||
wire.Bind(new(secrets.ProvidersRegistrar), new(*secretsManager.SecretsService)),
|
||||
secretsDatabase.ProvideSecretsStore,
|
||||
wire.Bind(new(secrets.Store), new(*secretsDatabase.SecretsStoreImpl)),
|
||||
grafanads.ProvideService,
|
||||
|
@ -39,3 +39,13 @@ func (f FakeSecretsService) GetDecryptedValue(_ context.Context, sjd map[string]
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func (f FakeSecretsService) CurrentProviderID() string {
|
||||
return "fakeProvider"
|
||||
}
|
||||
|
||||
func (f FakeSecretsService) GetProviders() map[string]secrets.Provider {
|
||||
return make(map[string]secrets.Provider)
|
||||
}
|
||||
|
||||
func (f FakeSecretsService) RegisterProvider(_ string, _ secrets.Provider) {}
|
||||
|
@ -36,14 +36,15 @@ func ProvideSecretsService(store secrets.Store, bus bus.Bus, enc encryption.Serv
|
||||
providers := map[string]secrets.Provider{
|
||||
defaultProvider: grafana.New(settings, enc),
|
||||
}
|
||||
currentProvider := settings.KeyValue("security", "encryption_provider").MustString(defaultProvider)
|
||||
|
||||
s := &SecretsService{
|
||||
store: store,
|
||||
bus: bus,
|
||||
enc: enc,
|
||||
settings: settings,
|
||||
currentProvider: defaultProvider,
|
||||
providers: providers,
|
||||
currentProvider: currentProvider,
|
||||
dataKeyCache: make(map[string]dataKeyCacheItem),
|
||||
}
|
||||
|
||||
@ -257,3 +258,15 @@ func (s *SecretsService) dataKey(ctx context.Context, name string) ([]byte, erro
|
||||
|
||||
return decrypted, nil
|
||||
}
|
||||
|
||||
func (s *SecretsService) RegisterProvider(providerID string, provider secrets.Provider) {
|
||||
s.providers[providerID] = provider
|
||||
}
|
||||
|
||||
func (s *SecretsService) CurrentProviderID() string {
|
||||
return s.currentProvider
|
||||
}
|
||||
|
||||
func (s *SecretsService) GetProviders() map[string]secrets.Provider {
|
||||
return s.providers
|
||||
}
|
||||
|
@ -4,15 +4,19 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
"github.com/grafana/grafana/pkg/services/secrets/database"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
func TestSecrets_EnvelopeEncryption(t *testing.T) {
|
||||
func TestSecretsService_EnvelopeEncryption(t *testing.T) {
|
||||
store := database.ProvideSecretsStore(sqlstore.InitTestDB(t))
|
||||
svc := SetupTestService(t, store)
|
||||
ctx := context.Background()
|
||||
@ -141,3 +145,42 @@ func TestSecretsService_DataKeys(t *testing.T) {
|
||||
assert.Nil(t, res)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSecretsService_GetCurrentProvider(t *testing.T) {
|
||||
t.Run("When encryption_provider is not specified explicitly, should use 'secretKey' as a current provider", func(t *testing.T) {
|
||||
cfg := `[security]
|
||||
secret_key = sdDkslslld`
|
||||
|
||||
raw, err := ini.Load([]byte(cfg))
|
||||
require.NoError(t, err)
|
||||
settings := &setting.OSSImpl{Cfg: &setting.Cfg{Raw: raw}}
|
||||
|
||||
svc := ProvideSecretsService(
|
||||
database.ProvideSecretsStore(sqlstore.InitTestDB(t)),
|
||||
bus.New(),
|
||||
ossencryption.ProvideService(),
|
||||
settings,
|
||||
)
|
||||
|
||||
assert.Equal(t, "secretKey", svc.currentProvider)
|
||||
})
|
||||
|
||||
t.Run("When encryption_provider value is set, should use it as a current provider", func(t *testing.T) {
|
||||
cfg := `[security]
|
||||
secret_key = sdDkslslld
|
||||
encryption_provider = awskms.second_key`
|
||||
|
||||
raw, err := ini.Load([]byte(cfg))
|
||||
require.NoError(t, err)
|
||||
settings := &setting.OSSImpl{Cfg: &setting.Cfg{Raw: raw}}
|
||||
|
||||
svc := ProvideSecretsService(
|
||||
database.ProvideSecretsStore(sqlstore.InitTestDB(t)),
|
||||
bus.New(),
|
||||
ossencryption.ProvideService(),
|
||||
settings,
|
||||
)
|
||||
|
||||
assert.Equal(t, "awskms.second_key", svc.currentProvider)
|
||||
})
|
||||
}
|
||||
|
@ -16,6 +16,12 @@ type Service interface {
|
||||
GetDecryptedValue(ctx context.Context, sjd map[string][]byte, key, fallback string) string
|
||||
}
|
||||
|
||||
type ProvidersRegistrar interface {
|
||||
CurrentProviderID() string
|
||||
GetProviders() map[string]Provider
|
||||
RegisterProvider(providerID string, provider Provider)
|
||||
}
|
||||
|
||||
// Store defines methods to interact with secrets storage
|
||||
type Store interface {
|
||||
GetDataKey(ctx context.Context, name string) (*DataKey, error)
|
||||
|
Loading…
Reference in New Issue
Block a user