fleet icon indicating copy to clipboard operation
fleet copied to clipboard

Windows Update CSP not being deployed when using GitOps.

Open tux234 opened this issue 1 month ago • 3 comments

Fleet version: 4.77

Web browser and operating system: N/A (Server-side bug)


💥 Actual behavior

Gong Snippet: https://us-65885.app.gong.io/call?id=5494040290920463199&highlights=%5B%7B%22type%22%3A%22SHARE%22%2C%22from%22%3A1234%2C%22to%22%3A1539%7D%5D

When Windows OS update settings (deadline_days and grace_period_days) are configured via GitOps YAML and applied with fleetctl apply, the configuration is saved to Fleet but the Windows Update CSP profiles are never deployed to enrolled Windows devices.

Observable symptoms:

  • CSP never appears in Windows registry under HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Update
  • No Windows Update policy activity in Windows event logs
  • Windows devices don't receive or apply the update deadlines
  • Fleet UI shows configuration as saved, but devices remain unmanaged for OS updates

However, when the same Windows update configuration is set through the Fleet UI (team settings → OS updates), the CSP deploys immediately and correctly to devices.

🛠️ To fix

Root Cause:

File: ee/server/service/teams.go Function: editTeamFromSpec (GitOps configuration path)

The GitOps code path at lines 1304-1306 saves Windows update settings but never triggers CSP deployment:

if spec.MDM.WindowsUpdates.DeadlineDays.Set || spec.MDM.WindowsUpdates.GracePeriodDays.Set {
    team.Config.MDM.WindowsUpdates = spec.MDM.WindowsUpdates
}
// Missing: No mdmWindowsUpdatesEdited flag tracking
// Missing: No call to mdmWindowsEnableOSUpdates() or mdmWindowsDisableOSUpdates()

Pattern Inconsistency:

All other OS update types (macOS, iOS, iPadOS) correctly track changes and trigger profile deployment:

  • macOS (lines 1289-1292, 1577-1580): ✅ Flag tracked, ✅ Deployment called
  • iOS (lines 1294-1297, 1582-1585): ✅ Flag tracked, ✅ Deployment called
  • iPadOS (lines 1299-1302, 1587-1590): ✅ Flag tracked, ✅ Deployment called
  • Windows (lines 1304-1306): ❌ Flag NOT tracked, ❌ Deployment NOT called

Fix:

Add Windows CSP deployment logic following the same pattern as the other OS types.

Step 1: Track when Windows updates are edited (modify lines 1304-1306):

var mdmWindowsUpdatesEdited bool
if spec.MDM.WindowsUpdates.DeadlineDays.Set || spec.MDM.WindowsUpdates.GracePeriodDays.Set {
    team.Config.MDM.WindowsUpdates = spec.MDM.WindowsUpdates
    mdmWindowsUpdatesEdited = true  // ← ADD THIS LINE
}

Step 2: Trigger CSP deployment after SaveTeam() (add after line 1591, following the iPadOS block):

if mdmWindowsUpdatesEdited {
    var deadline, grace *int
    if team.Config.MDM.WindowsUpdates.DeadlineDays.Valid {
        deadline = &team.Config.MDM.WindowsUpdates.DeadlineDays.Value
    }
    if team.Config.MDM.WindowsUpdates.GracePeriodDays.Valid {
        grace = &team.Config.MDM.WindowsUpdates.GracePeriodDays.Value
    }

    if deadline != nil {
        if err := svc.mdmWindowsEnableOSUpdates(ctx, &team.ID, team.Config.MDM.WindowsUpdates); err != nil {
            return ctxerr.Wrap(ctx, err, "enable team windows OS updates")
        }
    } else {
        if err := svc.mdmWindowsDisableOSUpdates(ctx, &team.ID); err != nil {
            return ctxerr.Wrap(ctx, err, "disable team windows OS updates")
        }
    }
}

This matches the pattern used by ModifyTeam() (UI path, lines 379-394), which works correctly.

Note on activities: There's a TODO comment at line 1352-1353 about whether to create activities for GitOps OS update changes. The fix above omits activity creation to match the current behavior for macOS/iOS/iPadOS via GitOps, but this can be added if the team decides activities should be created.

🧑‍💻 Steps to reproduce

These steps:

  • [x] Have been confirmed to consistently lead to reproduction in Fleet.
  • [ ] Describe the workflow that led to the error, but have not yet been reproduced in multiple Fleet instances.
  1. Set up Fleet with Windows MDM configured

    • Ensure Fleet server has Windows MDM enabled and configured
    • Enroll at least one Windows device via MDM
  2. Enable GitOps

    • Create or use an existing team
    • Enable GitOps mode
  3. Configure Windows OS updates via GitOps YAML

    • Create a team spec YAML file:
      apiVersion: v1
      kind: team
      spec:
        name: test-team
        mdm:
          windows_updates:
            deadline_days: 7
            grace_period_days: 2
      
  4. Apply the configuration

    • Run: fleetctl apply -f team-spec.yaml
    • Confirm: Fleet UI shows the Windows update settings saved for the team
  5. Check Windows device

    • Observe: CSP profile NOT present in HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Update
    • Observe: No Windows Update policy events in event logs
    • Observe: Windows Update behavior unchanged (no deadline enforcement)
  6. Compare with UI path (workaround)

    • Disable GitOps for the team
    • In Fleet UI, go to team → OS updates → Windows
    • Change grace period to a different value (e.g., 1 day)
    • Save
    • Observe: CSP deploys immediately, appears in registry and event logs

🕯️ More info (optional)

Comparison with UI Code Path:

The UI code path (ModifyTeam() in ee/server/service/teams.go, lines 212-408) correctly handles Windows update changes:

  • Line 217: Detects changes with windowsUpdatesUpdated flag
  • Line 389: Calls mdmWindowsEnableOSUpdates() to deploy CSP
  • Lines 396-407: Creates activity for audit trail

The GitOps path is missing steps 2 and 3.

Related Files:

  • ee/server/service/mdm.go: Contains mdmWindowsEnableOSUpdates() and mdmWindowsDisableOSUpdates()
  • datastore/mysql/microsoft_mdm.go: Profile deployment via BulkSetPendingMDMHostProfiles()

Testing checklist after fix:

  • [ ] GitOps: Configure Windows updates via YAML → CSP deployed to devices
  • [ ] GitOps: Clear deadline_days → CSP removed from devices
  • [ ] GitOps: Update existing Windows update settings → CSP updated on devices
  • [ ] UI: Verify existing UI path still works correctly (regression test)
  • [ ] Verify CSP appears in Windows registry after GitOps deployment
  • [ ] Verify Windows event logs show policy application

tux234 avatar Dec 11 '25 19:12 tux234

Hey @tux234 it looks like you're working on this bug so I moved it to :help-it-and-enablement board.

Please feel free to add it back to drafting (:product label) if Product Design can help!

noahtalerman avatar Dec 12 '25 14:12 noahtalerman

Thanks @noahtalerman!

I gave it a shot, and it looks like all tests are passing, so I got the PR up for review. Let me know how I else I can help with this!

tux234 avatar Dec 12 '25 15:12 tux234

@tux234 nice! I moved this bug over to the #g-mdm board to help us w/ review and QA. FYI @JordanMontgomery @georgekarrv

noahtalerman avatar Dec 12 '25 16:12 noahtalerman