Provisioning: Decrypt using Secrets Service in Operators (#110589)

* Use real secrets servicer decrypter

* Add also server name just in case
This commit is contained in:
Roberto Jiménez Sánchez
2025-09-04 16:18:14 +02:00
committed by GitHub
parent 000ada4cd1
commit 57ea65dc42
+48 -24
View File
@@ -1,7 +1,6 @@
package provisioning
import (
"context"
"crypto/x509"
"fmt"
"net/http"
@@ -12,6 +11,7 @@ import (
"k8s.io/client-go/rest"
"k8s.io/client-go/transport"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/setting"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
@@ -20,7 +20,7 @@ import (
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/github"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/local"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
secretdecrypt "github.com/grafana/grafana/pkg/registry/apis/secret/decrypt"
)
// provisioningControllerConfig contains the configuration that overlaps for the jobs and repo controllers
@@ -34,6 +34,12 @@ type provisioningControllerConfig struct {
// [grpc_client_authentication]
// token =
// token_exchange_url =
// [secrets_manager]
// grpc_server_address =
// grpc_server_tls_server_name =
// grpc_server_use_tls =
// grpc_server_tls_ca_file =
// grpc_server_tls_skip_verify =
// [operator]
// provisioning_server_url =
// tls_insecure =
@@ -48,6 +54,9 @@ func setupFromConfig(cfg *setting.Cfg) (controllerCfg *provisioningControllerCon
if cfg == nil {
return nil, fmt.Errorf("no configuration available")
}
// TODO: we should setup tracing properly
// https://github.com/grafana/git-ui-sync-project/issues/507
tracer := tracing.NewNoopTracerService()
gRPCAuth := cfg.SectionWithEnvOverrides("grpc_client_authentication")
token := gRPCAuth.Key("token").String()
@@ -96,8 +105,12 @@ func setupFromConfig(cfg *setting.Cfg) (controllerCfg *provisioningControllerCon
return nil, fmt.Errorf("failed to create provisioning client: %w", err)
}
// TODO: Replace with a real decrypter that uses the Grafana secret service
repoFactory, err := setupRepoFactory(cfg, emptyValuesDecrypter, provisioningClient)
decrypter, err := setupDecrypter(cfg, tracer, tokenExchangeClient)
if err != nil {
return nil, fmt.Errorf("failed to setup decrypter: %w", err)
}
repoFactory, err := setupRepoFactory(cfg, decrypter, provisioningClient)
if err != nil {
return nil, fmt.Errorf("failed to setup repository getter: %w", err)
}
@@ -138,26 +151,6 @@ func buildTLSConfig(insecure bool, certFile, keyFile, caFile string) (rest.TLSCl
return tlsConfig, nil
}
// emptyValuesDecrypter is a decrypter that always returns empty values.
// This is a temporary implementation and should be replaced with a real decrypter.
// TODO: remove this and use a real decrypter that uses the Grafana secret service
func emptyValuesDecrypter(r *provisioning.Repository) repository.SecureValues {
return &emptyValues{}
}
// emptyValues is a that always returns empty values.
// This is a temporary implementation and should be replaced with a real decrypter.
// TODO: remove this and use a real decrypter that uses the Grafana secret service
type emptyValues struct{}
func (s *emptyValues) Token(ctx context.Context) (common.RawSecureValue, error) {
return common.NewSecretValue(""), nil
}
func (s *emptyValues) WebhookSecret(ctx context.Context) (common.RawSecureValue, error) {
return common.NewSecretValue(""), nil
}
func setupRepoFactory(
cfg *setting.Cfg,
decrypter repository.Decrypter,
@@ -214,3 +207,34 @@ func setupRepoFactory(
return repoFactory, nil
}
func setupDecrypter(cfg *setting.Cfg, tracer tracing.Tracer, tokenExchangeClient *authn.TokenExchangeClient) (decrypter repository.Decrypter, err error) {
secretsSec := cfg.SectionWithEnvOverrides("secrets_manager")
if secretsSec == nil {
return nil, fmt.Errorf("no [secrets_manager] section found in config")
}
address := secretsSec.Key("grpc_server_address").String()
if address == "" {
return nil, fmt.Errorf("grpc_server_address is required in [secrets_manager] section")
}
secretsTls := secretdecrypt.TLSConfig{
UseTLS: secretsSec.Key("grpc_server_use_tls").MustBool(true),
CAFile: secretsSec.Key("grpc_server_tls_ca_file").String(),
ServerName: secretsSec.Key("grpc_server_tls_server_name").String(),
InsecureSkipVerify: secretsSec.Key("grpc_server_tls_skip_verify").MustBool(false),
}
decryptSvc, err := secretdecrypt.NewGRPCDecryptClientWithTLS(
tokenExchangeClient,
tracer,
address,
secretsTls,
)
if err != nil {
return nil, fmt.Errorf("create decrypt service: %w", err)
}
return repository.ProvideDecrypter(decryptSvc), nil
}