diff --git a/changes/issue-12257-windows-mdm-feature-flag b/changes/issue-12257-windows-mdm-feature-flag new file mode 100644 index 0000000000..4c9f3d2392 --- /dev/null +++ b/changes/issue-12257-windows-mdm-feature-flag @@ -0,0 +1 @@ +* Added the `FLEET_DEV_MDM_ENABLED` environment variable to enable the Windows MDM feature during its development and beta period. diff --git a/server/config/config.go b/server/config/config.go index c24dc95f2c..0059e43963 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -1658,3 +1658,13 @@ func SetTestMDMConfig(t testing.TB, cfg *FleetConfig, cert, key []byte, appleBMT cfg.MDM.AppleSCEPSignerValidityDays = 365 cfg.MDM.AppleSCEPChallenge = "testchallenge" } + +// Undocumented feature flag for Windows MDM, used to determine if the Windows +// MDM feature is visible in the UI and can be enabled. More details here: +// https://github.com/fleetdm/fleet/issues/12257 +// +// TODO: remove this flag once the Windows MDM feature is ready for +// release. +func IsMDMFeatureFlagEnabled() bool { + return os.Getenv("FLEET_DEV_MDM_ENABLED") == "1" +} diff --git a/server/service/appconfig.go b/server/service/appconfig.go index 83dc1eef1c..2b7cef1632 100644 --- a/server/service/appconfig.go +++ b/server/service/appconfig.go @@ -15,6 +15,7 @@ import ( "net/url" "github.com/fleetdm/fleet/v4/server/authz" + "github.com/fleetdm/fleet/v4/server/config" authz_ctx "github.com/fleetdm/fleet/v4/server/contexts/authz" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" "github.com/fleetdm/fleet/v4/server/contexts/license" @@ -47,6 +48,17 @@ type appConfigResponseFields struct { // SandboxEnabled is true if fleet serve was ran with server.sandbox_enabled=true SandboxEnabled bool `json:"sandbox_enabled,omitempty"` Err error `json:"error,omitempty"` + + // MDMEnabled is true if fleet serve was started with + // FLEET_DEV_MDM_ENABLED=1. + // + // Undocumented feature flag for Windows MDM, used to determine if the + // Windows MDM feature is visible in the UI and can be enabled. More details + // here: https://github.com/fleetdm/fleet/issues/12257 + // + // TODO: remove this flag once the Windows MDM feature is ready for + // release. + MDMEnabled bool `json:"mdm_enabled,omitempty"` } // UnmarshalJSON implements the json.Unmarshaler interface to make sure we serialize @@ -73,7 +85,7 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se if !ok { return nil, errors.New("could not fetch user") } - config, err := svc.AppConfigObfuscated(ctx) + appConfig, err := svc.AppConfigObfuscated(ctx) if err != nil { return nil, err } @@ -103,30 +115,30 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se var ssoSettings *fleet.SSOSettings var agentOptions *json.RawMessage if vc.User.GlobalRole != nil && *vc.User.GlobalRole == fleet.RoleAdmin { - smtpSettings = config.SMTPSettings - ssoSettings = config.SSOSettings - agentOptions = config.AgentOptions + smtpSettings = appConfig.SMTPSettings + ssoSettings = appConfig.SSOSettings + agentOptions = appConfig.AgentOptions } transparencyURL := fleet.DefaultTransparencyURL // Fleet Premium license is required for custom transparency url - if license.IsPremium() && config.FleetDesktop.TransparencyURL != "" { - transparencyURL = config.FleetDesktop.TransparencyURL + if license.IsPremium() && appConfig.FleetDesktop.TransparencyURL != "" { + transparencyURL = appConfig.FleetDesktop.TransparencyURL } fleetDesktop := fleet.FleetDesktopSettings{TransparencyURL: transparencyURL} - if config.OrgInfo.ContactURL == "" { - config.OrgInfo.ContactURL = fleet.DefaultOrgInfoContactURL + if appConfig.OrgInfo.ContactURL == "" { + appConfig.OrgInfo.ContactURL = fleet.DefaultOrgInfoContactURL } - features := config.Features + features := appConfig.Features response := appConfigResponse{ AppConfig: fleet.AppConfig{ - OrgInfo: config.OrgInfo, - ServerSettings: config.ServerSettings, + OrgInfo: appConfig.OrgInfo, + ServerSettings: appConfig.ServerSettings, Features: features, - VulnerabilitySettings: config.VulnerabilitySettings, - HostExpirySettings: config.HostExpirySettings, + VulnerabilitySettings: appConfig.VulnerabilitySettings, + HostExpirySettings: appConfig.HostExpirySettings, SMTPSettings: smtpSettings, SSOSettings: ssoSettings, @@ -134,9 +146,9 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se FleetDesktop: fleetDesktop, - WebhookSettings: config.WebhookSettings, - Integrations: config.Integrations, - MDM: config.MDM, + WebhookSettings: appConfig.WebhookSettings, + Integrations: appConfig.Integrations, + MDM: appConfig.MDM, }, appConfigResponseFields: appConfigResponseFields{ UpdateInterval: updateIntervalConfig, @@ -145,6 +157,7 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se Logging: loggingConfig, Email: emailConfig, SandboxEnabled: svc.SandboxEnabled(), + MDMEnabled: config.IsMDMFeatureFlagEnabled(), }, } return response, nil diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index 54c820fe22..b43d313193 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -4663,6 +4663,7 @@ func (s *integrationTestSuite) TestAppConfig() { assert.Equal(t, "free", acResp.License.Tier) assert.Equal(t, "FleetTest", acResp.OrgInfo.OrgName) // set in SetupSuite assert.False(t, acResp.MDM.AppleBMTermsExpired) + assert.False(t, acResp.MDMEnabled) // set the apple BM terms expired flag, and the enabled and configured flags, // we'll check again at the end of this test to make sure they weren't diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index bf82ebf8a6..6e18c70be2 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -54,6 +54,8 @@ import ( ) func TestIntegrationsMDM(t *testing.T) { + t.Setenv("FLEET_DEV_MDM_ENABLED", "1") + testingSuite := new(integrationMDMTestSuite) testingSuite.s = &testingSuite.Suite suite.Run(t, testingSuite) @@ -1721,6 +1723,15 @@ func (s *integrationMDMTestSuite) TestMDMAppleConfigProfileCRUD() { s.DoJSON("DELETE", deletePath, nil, http.StatusBadRequest, &deleteResp) } +func (s *integrationMDMTestSuite) TestAppConfigMDMEnabled() { + t := s.T() + + // the feature flag is enabled for the MDM test suite + var acResp appConfigResponse + s.DoJSON("GET", "/api/latest/fleet/config", nil, http.StatusOK, &acResp) + assert.True(t, acResp.MDMEnabled) +} + func (s *integrationMDMTestSuite) TestAppConfigMDMAppleProfiles() { t := s.T()