ManagedServiceAccounts: Add a config option to disable the feature on-prem (#93571)

* ManagedServiceAccounts: Add a config option to disabled by default

* Update log in pkg/services/extsvcauth/registry/service.go

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
pull/93783/head^2
Gabriel MABILLE 9 months ago committed by GitHub
parent 2cfba519f1
commit 7928245eb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      conf/defaults.ini
  2. 3
      conf/sample.ini
  3. 4
      pkg/api/plugins.go
  4. 4
      pkg/services/accesscontrol/acimpl/service.go
  5. 2
      pkg/services/accesscontrol/acimpl/service_test.go
  6. 30
      pkg/services/extsvcauth/registry/service.go
  7. 3
      pkg/services/extsvcauth/registry/service_test.go
  8. 6
      pkg/services/pluginsintegration/serviceregistration/serviceregistration.go
  9. 3
      pkg/services/serviceaccounts/api/api.go
  10. 12
      pkg/services/serviceaccounts/extsvcaccounts/service.go
  11. 3
      pkg/services/serviceaccounts/extsvcaccounts/service_test.go
  12. 2
      pkg/services/serviceaccounts/proxy/service.go
  13. 5
      pkg/setting/setting.go

@ -615,6 +615,9 @@ id_response_header_prefix = X-Grafana
# The header value will encode the namespace ("user:<id>", "api-key:<id>", "service-account:<id>") # The header value will encode the namespace ("user:<id>", "api-key:<id>", "service-account:<id>")
id_response_header_namespaces = user api-key service-account id_response_header_namespaces = user api-key service-account
# Enables the use of managed service accounts for plugin authentication
managed_service_accounts_enabled = false
#################################### SSO Settings ########################### #################################### SSO Settings ###########################
[sso_settings] [sso_settings]
# interval for reloading the SSO Settings from the database # interval for reloading the SSO Settings from the database

@ -619,6 +619,9 @@
# The header value will encode the namespace ("user:<id>", "api-key:<id>", "service-account:<id>") # The header value will encode the namespace ("user:<id>", "api-key:<id>", "service-account:<id>")
;id_response_header_namespaces = user api-key service-account ;id_response_header_namespaces = user api-key service-account
# Enables the use of managed service accounts for plugin authentication
; managed_service_accounts_enabled = false
#################################### Anonymous Auth ###################### #################################### Anonymous Auth ######################
[auth.anonymous] [auth.anonymous]
# enable anonymous access # enable anonymous access

@ -144,7 +144,7 @@ func (hs *HTTPServer) GetPluginList(c *contextmodel.ReqContext) response.Respons
AngularDetected: pluginDef.Angular.Detected, AngularDetected: pluginDef.Angular.Detected,
} }
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagExternalServiceAccounts) { if hs.Cfg.ManagedServiceAccountsEnabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagExternalServiceAccounts) {
listItem.IAM = pluginDef.IAM listItem.IAM = pluginDef.IAM
} }
@ -484,7 +484,7 @@ func (hs *HTTPServer) InstallPlugin(c *contextmodel.ReqContext) response.Respons
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to install plugin", err) return response.ErrOrFallback(http.StatusInternalServerError, "Failed to install plugin", err)
} }
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagExternalServiceAccounts) { if hs.Cfg.ManagedServiceAccountsEnabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagExternalServiceAccounts) {
// This is a non-blocking function that verifies that the installer has // This is a non-blocking function that verifies that the installer has
// the permissions that the plugin requests to have on Grafana. // the permissions that the plugin requests to have on Grafana.
// If we want to make this blocking, the check will have to happen before or during the installation. // If we want to make this blocking, the check will have to happen before or during the installation.

@ -735,7 +735,7 @@ func (s *Service) SaveExternalServiceRole(ctx context.Context, cmd accesscontrol
ctx, span := tracer.Start(ctx, "accesscontrol.acimpl.SaveExternalServiceRole") ctx, span := tracer.Start(ctx, "accesscontrol.acimpl.SaveExternalServiceRole")
defer span.End() defer span.End()
if !s.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !s.cfg.ManagedServiceAccountsEnabled || !s.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) {
s.log.Debug("Registering an external service role is behind a feature flag, enable it to use this feature.") s.log.Debug("Registering an external service role is behind a feature flag, enable it to use this feature.")
return nil return nil
} }
@ -751,7 +751,7 @@ func (s *Service) DeleteExternalServiceRole(ctx context.Context, externalService
ctx, span := tracer.Start(ctx, "accesscontrol.acimpl.DeleteExternalServiceRole") ctx, span := tracer.Start(ctx, "accesscontrol.acimpl.DeleteExternalServiceRole")
defer span.End() defer span.End()
if !s.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !s.cfg.ManagedServiceAccountsEnabled || !s.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) {
s.log.Debug("Deleting an external service role is behind a feature flag, enable it to use this feature.") s.log.Debug("Deleting an external service role is behind a feature flag, enable it to use this feature.")
return nil return nil
} }

@ -900,6 +900,7 @@ func TestService_SaveExternalServiceRole(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ac := setupTestEnv(t) ac := setupTestEnv(t)
ac.cfg.ManagedServiceAccountsEnabled = true
ac.features = featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts) ac.features = featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts)
for _, r := range tt.runs { for _, r := range tt.runs {
err := ac.SaveExternalServiceRole(ctx, r.cmd) err := ac.SaveExternalServiceRole(ctx, r.cmd)
@ -946,6 +947,7 @@ func TestService_DeleteExternalServiceRole(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ac := setupTestEnv(t) ac := setupTestEnv(t)
ac.cfg.ManagedServiceAccountsEnabled = true
ac.features = featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts) ac.features = featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts)
if tt.initCmd != nil { if tt.initCmd != nil {

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/extsvcauth" "github.com/grafana/grafana/pkg/services/extsvcauth"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/serviceaccounts/extsvcaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/extsvcaccounts"
"github.com/grafana/grafana/pkg/setting"
) )
var _ extsvcauth.ExternalServiceRegistry = &Registry{} var _ extsvcauth.ExternalServiceRegistry = &Registry{}
@ -28,9 +29,9 @@ type serverLocker interface {
} }
type Registry struct { type Registry struct {
features featuremgmt.FeatureToggles enabled bool
logger log.Logger logger log.Logger
saReg extsvcauth.ExternalServiceRegistry saReg extsvcauth.ExternalServiceRegistry
// FIXME (gamab): we can remove this field and use the saReg.GetExternalServiceNames directly // FIXME (gamab): we can remove this field and use the saReg.GetExternalServiceNames directly
extSvcProviders map[string]extsvcauth.AuthProvider extSvcProviders map[string]extsvcauth.AuthProvider
@ -38,10 +39,11 @@ type Registry struct {
serverLock serverLocker serverLock serverLocker
} }
func ProvideExtSvcRegistry(saSvc *extsvcaccounts.ExtSvcAccountsService, serverLock *serverlock.ServerLockService, features featuremgmt.FeatureToggles) *Registry { func ProvideExtSvcRegistry(cfg *setting.Cfg, saSvc *extsvcaccounts.ExtSvcAccountsService, serverLock *serverlock.ServerLockService, features featuremgmt.FeatureToggles) *Registry {
enabled := features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts) && cfg.ManagedServiceAccountsEnabled
return &Registry{ return &Registry{
extSvcProviders: map[string]extsvcauth.AuthProvider{}, extSvcProviders: map[string]extsvcauth.AuthProvider{},
features: features, enabled: enabled,
lock: sync.Mutex{}, lock: sync.Mutex{},
logger: log.New("extsvcauth.registry"), logger: log.New("extsvcauth.registry"),
saReg: saSvc, saReg: saSvc,
@ -110,8 +112,12 @@ func (r *Registry) RemoveExternalService(ctx context.Context, name string) error
switch provider { switch provider {
case extsvcauth.ServiceAccounts: case extsvcauth.ServiceAccounts:
if !r.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !r.enabled {
r.logger.Debug("Skipping External Service removal, flag disabled", "service", name, "flag", featuremgmt.FlagExternalServiceAccounts) r.logger.Warn("Skipping External Service authentication, flag or configuration option is disabled",
"service", name,
"flag", featuremgmt.FlagExternalServiceAccounts,
"option", "ManagedServiceAccountsEnabled",
)
return nil return nil
} }
r.logger.Debug("Routing External Service removal to the External Service Account service", "service", name) r.logger.Debug("Routing External Service removal to the External Service Account service", "service", name)
@ -140,8 +146,12 @@ func (r *Registry) SaveExternalService(ctx context.Context, cmd *extsvcauth.Exte
switch cmd.AuthProvider { switch cmd.AuthProvider {
case extsvcauth.ServiceAccounts: case extsvcauth.ServiceAccounts:
if !r.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !r.enabled {
ctxLogger.Warn("Skipping External Service authentication, flag disabled", "service", cmd.Name, "flag", featuremgmt.FlagExternalServiceAccounts) ctxLogger.Warn("Skipping External Service authentication, flag or configuration option disabled",
"service", cmd.Name,
"flag", featuremgmt.FlagExternalServiceAccounts,
"option", "ManagedServiceAccountsEnabled",
)
return return
} }
ctxLogger.Debug("Routing the External Service registration to the External Service Account service", "service", cmd.Name) ctxLogger.Debug("Routing the External Service registration to the External Service Account service", "service", cmd.Name)
@ -160,7 +170,7 @@ func (r *Registry) SaveExternalService(ctx context.Context, cmd *extsvcauth.Exte
// retrieveExtSvcProviders fetches external services from store and map their associated provider // retrieveExtSvcProviders fetches external services from store and map their associated provider
func (r *Registry) retrieveExtSvcProviders(ctx context.Context) (map[string]extsvcauth.AuthProvider, error) { func (r *Registry) retrieveExtSvcProviders(ctx context.Context) (map[string]extsvcauth.AuthProvider, error) {
extsvcs := map[string]extsvcauth.AuthProvider{} extsvcs := map[string]extsvcauth.AuthProvider{}
if r.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if r.enabled {
names, err := r.saReg.GetExternalServiceNames(ctx) names, err := r.saReg.GetExternalServiceNames(ctx)
if err != nil { if err != nil {
return nil, err return nil, err

@ -8,7 +8,6 @@ import (
"github.com/grafana/grafana/pkg/infra/serverlock" "github.com/grafana/grafana/pkg/infra/serverlock"
"github.com/grafana/grafana/pkg/services/extsvcauth" "github.com/grafana/grafana/pkg/services/extsvcauth"
"github.com/grafana/grafana/pkg/services/extsvcauth/tests" "github.com/grafana/grafana/pkg/services/extsvcauth/tests"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -30,7 +29,7 @@ func setupTestEnv(t *testing.T) *TestEnv {
env := TestEnv{} env := TestEnv{}
env.saReg = tests.NewExternalServiceRegistryMock(t) env.saReg = tests.NewExternalServiceRegistryMock(t)
env.r = &Registry{ env.r = &Registry{
features: featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts), enabled: true,
logger: log.New("extsvcauth.registry.test"), logger: log.New("extsvcauth.registry.test"),
saReg: env.saReg, saReg: env.saReg,
extSvcProviders: map[string]extsvcauth.AuthProvider{}, extSvcProviders: map[string]extsvcauth.AuthProvider{},

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/services/extsvcauth" "github.com/grafana/grafana/pkg/services/extsvcauth"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
"github.com/grafana/grafana/pkg/setting"
) )
type Service struct { type Service struct {
@ -20,9 +21,10 @@ type Service struct {
settingsSvc pluginsettings.Service settingsSvc pluginsettings.Service
} }
func ProvideService(features featuremgmt.FeatureToggles, reg extsvcauth.ExternalServiceRegistry, settingsSvc pluginsettings.Service) *Service { func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, reg extsvcauth.ExternalServiceRegistry, settingsSvc pluginsettings.Service) *Service {
enabled := features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts) && cfg.ManagedServiceAccountsEnabled
s := &Service{ s := &Service{
featureEnabled: features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts), featureEnabled: enabled,
log: log.New("plugins.external.registration"), log: log.New("plugins.external.registration"),
reg: reg, reg: reg,
settingsSvc: settingsSvc, settingsSvc: settingsSvc,

@ -40,6 +40,7 @@ func NewServiceAccountsAPI(
permissionService accesscontrol.ServiceAccountPermissionsService, permissionService accesscontrol.ServiceAccountPermissionsService,
features featuremgmt.FeatureToggles, features featuremgmt.FeatureToggles,
) *ServiceAccountsAPI { ) *ServiceAccountsAPI {
enabled := features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts) && cfg.ManagedServiceAccountsEnabled
return &ServiceAccountsAPI{ return &ServiceAccountsAPI{
cfg: cfg, cfg: cfg,
service: service, service: service,
@ -48,7 +49,7 @@ func NewServiceAccountsAPI(
RouterRegister: routerRegister, RouterRegister: routerRegister,
log: log.New("serviceaccounts.api"), log: log.New("serviceaccounts.api"),
permissionService: permissionService, permissionService: permissionService,
isExternalSAEnabled: features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts), isExternalSAEnabled: enabled,
} }
} }

@ -28,12 +28,12 @@ import (
type ExtSvcAccountsService struct { type ExtSvcAccountsService struct {
acSvc ac.Service acSvc ac.Service
defaultOrgID int64 defaultOrgID int64
features featuremgmt.FeatureToggles
logger log.Logger logger log.Logger
metrics *metrics metrics *metrics
saSvc sa.Service saSvc sa.Service
skvStore kvstore.SecretsKVStore skvStore kvstore.SecretsKVStore
tracer tracing.Tracer tracer tracing.Tracer
enabled bool
} }
func ProvideExtSvcAccountsService(acSvc ac.Service, cfg *setting.Cfg, bus bus.Bus, db db.DB, features featuremgmt.FeatureToggles, reg prometheus.Registerer, saSvc *manager.ServiceAccountsService, secretsSvc secrets.Service, tracer tracing.Tracer) *ExtSvcAccountsService { func ProvideExtSvcAccountsService(acSvc ac.Service, cfg *setting.Cfg, bus bus.Bus, db db.DB, features featuremgmt.FeatureToggles, reg prometheus.Registerer, saSvc *manager.ServiceAccountsService, secretsSvc secrets.Service, tracer tracing.Tracer) *ExtSvcAccountsService {
@ -43,12 +43,12 @@ func ProvideExtSvcAccountsService(acSvc ac.Service, cfg *setting.Cfg, bus bus.Bu
defaultOrgID: cfg.DefaultOrgID(), defaultOrgID: cfg.DefaultOrgID(),
logger: logger, logger: logger,
saSvc: saSvc, saSvc: saSvc,
features: features,
skvStore: kvstore.NewSQLSecretsKVStore(db, secretsSvc, logger), // Using SQL store to avoid a cyclic dependency skvStore: kvstore.NewSQLSecretsKVStore(db, secretsSvc, logger), // Using SQL store to avoid a cyclic dependency
tracer: tracer, tracer: tracer,
enabled: cfg.ManagedServiceAccountsEnabled && features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts),
} }
if features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts) { if esa.enabled {
// Register the metrics // Register the metrics
esa.metrics = newMetrics(reg, esa.defaultOrgID, saSvc, logger) esa.metrics = newMetrics(reg, esa.defaultOrgID, saSvc, logger)
@ -138,7 +138,7 @@ func (esa *ExtSvcAccountsService) GetExternalServiceNames(ctx context.Context) (
// SaveExternalService creates, updates or delete a service account (and its token) with the requested permissions. // SaveExternalService creates, updates or delete a service account (and its token) with the requested permissions.
func (esa *ExtSvcAccountsService) SaveExternalService(ctx context.Context, cmd *extsvcauth.ExternalServiceRegistration) (*extsvcauth.ExternalService, error) { func (esa *ExtSvcAccountsService) SaveExternalService(ctx context.Context, cmd *extsvcauth.ExternalServiceRegistration) (*extsvcauth.ExternalService, error) {
// This is double proofing, we should never reach here anyway the flags have already been checked. // This is double proofing, we should never reach here anyway the flags have already been checked.
if !esa.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !esa.enabled {
esa.logger.FromContext(ctx).Warn("This feature is behind a feature flag, please set it if you want to save external services") esa.logger.FromContext(ctx).Warn("This feature is behind a feature flag, please set it if you want to save external services")
return nil, nil return nil, nil
} }
@ -184,7 +184,7 @@ func (esa *ExtSvcAccountsService) SaveExternalService(ctx context.Context, cmd *
func (esa *ExtSvcAccountsService) RemoveExternalService(ctx context.Context, name string) error { func (esa *ExtSvcAccountsService) RemoveExternalService(ctx context.Context, name string) error {
// This is double proofing, we should never reach here anyway the flags have already been checked. // This is double proofing, we should never reach here anyway the flags have already been checked.
if !esa.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !esa.enabled {
esa.logger.Warn("This feature is behind a feature flag, please set it if you want to save external services") esa.logger.Warn("This feature is behind a feature flag, please set it if you want to save external services")
return nil return nil
} }
@ -225,7 +225,7 @@ func (esa *ExtSvcAccountsService) RemoveExtSvcAccount(ctx context.Context, orgID
// ManageExtSvcAccount creates, updates or deletes the service account associated with an external service // ManageExtSvcAccount creates, updates or deletes the service account associated with an external service
func (esa *ExtSvcAccountsService) ManageExtSvcAccount(ctx context.Context, cmd *sa.ManageExtSvcAccountCmd) (int64, error) { func (esa *ExtSvcAccountsService) ManageExtSvcAccount(ctx context.Context, cmd *sa.ManageExtSvcAccountCmd) (int64, error) {
// This is double proofing, we should never reach here anyway the flags have already been checked. // This is double proofing, we should never reach here anyway the flags have already been checked.
if !esa.features.IsEnabled(ctx, featuremgmt.FlagExternalServiceAccounts) { if !esa.enabled {
esa.logger.FromContext(ctx).Warn("This feature is behind a feature flag, please set it if you want to save external services") esa.logger.FromContext(ctx).Warn("This feature is behind a feature flag, please set it if you want to save external services")
return 0, nil return 0, nil
} }

@ -41,6 +41,7 @@ func setupTestEnv(t *testing.T) *TestEnv {
t.Helper() t.Helper()
cfg := setting.NewCfg() cfg := setting.NewCfg()
cfg.ManagedServiceAccountsEnabled = true
fmgt := featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts) fmgt := featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAccounts)
env := &TestEnv{ env := &TestEnv{
@ -50,13 +51,13 @@ func setupTestEnv(t *testing.T) *TestEnv {
} }
logger := log.New("extsvcaccounts.test") logger := log.New("extsvcaccounts.test")
env.S = &ExtSvcAccountsService{ env.S = &ExtSvcAccountsService{
enabled: true,
acSvc: acimpl.ProvideOSSService( acSvc: acimpl.ProvideOSSService(
cfg, env.AcStore, &resourcepermissions.FakeActionSetSvc{}, cfg, env.AcStore, &resourcepermissions.FakeActionSetSvc{},
localcache.New(0, 0), fmgt, tracing.InitializeTracerForTest(), nil, nil, localcache.New(0, 0), fmgt, tracing.InitializeTracerForTest(), nil, nil,
permreg.ProvidePermissionRegistry(), permreg.ProvidePermissionRegistry(),
), ),
defaultOrgID: autoAssignOrgID, defaultOrgID: autoAssignOrgID,
features: fmgt,
logger: logger, logger: logger,
metrics: newMetrics(nil, autoAssignOrgID, env.SaSvc, logger), metrics: newMetrics(nil, autoAssignOrgID, env.SaSvc, logger),
saSvc: env.SaSvc, saSvc: env.SaSvc,

@ -38,7 +38,7 @@ func ProvideServiceAccountsProxy(
s := &ServiceAccountsProxy{ s := &ServiceAccountsProxy{
log: log.New("serviceaccounts.proxy"), log: log.New("serviceaccounts.proxy"),
proxiedService: proxiedService, proxiedService: proxiedService,
isProxyEnabled: features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts), isProxyEnabled: cfg.ManagedServiceAccountsEnabled && features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAccounts),
} }
serviceaccountsAPI := api.NewServiceAccountsAPI(cfg, s, ac, accesscontrolService, routeRegister, permissionService, features) serviceaccountsAPI := api.NewServiceAccountsAPI(cfg, s, ac, accesscontrolService, routeRegister, permissionService, features)

@ -245,6 +245,7 @@ type Cfg struct {
IDResponseHeaderEnabled bool IDResponseHeaderEnabled bool
IDResponseHeaderPrefix string IDResponseHeaderPrefix string
IDResponseHeaderNamespaces map[string]struct{} IDResponseHeaderNamespaces map[string]struct{}
ManagedServiceAccountsEnabled bool
// AWS Plugin Auth // AWS Plugin Auth
AWSAllowedAuthProviders []string AWSAllowedAuthProviders []string
@ -1668,6 +1669,10 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) {
for _, provider := range util.SplitString(providers) { for _, provider := range util.SplitString(providers) {
cfg.SSOSettingsConfigurableProviders[provider] = true cfg.SSOSettingsConfigurableProviders[provider] = true
} }
// Managed Service Accounts
cfg.ManagedServiceAccountsEnabled = auth.Key("managed_service_accounts_enabled").MustBool(false)
return nil return nil
} }

Loading…
Cancel
Save