Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fixing unreleased issue with vpp installs on byod#46108

Draft
georgekarrv wants to merge 1 commit into
mainfrom
gkarr-fix-byod-vpp
Draft

Fixing unreleased issue with vpp installs on byod#46108
georgekarrv wants to merge 1 commit into
mainfrom
gkarr-fix-byod-vpp

Conversation

@georgekarrv
Copy link
Copy Markdown
Member

@georgekarrv georgekarrv commented May 22, 2026

Summary

Three fixes for the BYOD/User-Enrollment VPP install flow shipped under #31138, all caught during QA on gkarr-fix-byod-vpp:

1. Switch VPP user registration from v2 (async) to v1 (sync)

The original implementation called Apple's /mdm/v2/users/create, which is asynchronous: a 200 response only confirms the registration was queued, with no userId returned. Fleet was storing the row as registered based on the eventId alone, which masked failures and left apple_user_id permanently NULL. Switched to Apple's legacy v1 registerVPPUserSrv endpoint, which returns the full user record (including Apple's userId) in the same response, so we know definitively whether registration succeeded.

  • New vpp.RegisterUser(token, clientUserID, managedAppleID) posts to https://vpp.itunes.apple.com/mdm/registerVPPUserSrv with the token in the request body (v1 doesn't use the Authorization header).
  • ensureVPPClientUser no longer writes "pending" rows on failure — v1's sync contract means we either succeed or surface the error.
  • Removed the now-unused v2 CreateUsers types and tests.

2. Show a clear error when an end user already has the app installed personally

On BYOD/User-Enrolled hosts, when an end user has already installed an app from the App Store outside of Fleet, Apple's InstallApplication command fails with "The app with iTunes Store ID <id> is already installed." (code 12042). Previously Fleet treated this as success and entered the InstalledApplicationList verification loop — which never resolves on User Enrollment, since Apple's managedAppsOnly: true filter doesn't return personally-installed apps. The install appeared stuck.

  • BYOD hosts now mark the install as failed instead of routing to verification, skip the retry path (the same install would just fail again), and surface the Figma-specified copy: "Failed. This app is already installed. Please delete app first, an install via self-service."
  • Fully-managed hosts retain the existing behavior — MDM can take ownership of personally-installed apps on those devices, so the success-treatment is correct there.

3. Self-heal a stale vpp_client_users cache against Apple

If Fleet's cached client_user_id ever drifts from Apple's record (DB restore from a stale backup, manual tampering, future bug), Apple rejects AssociateAssets with code 9609 "Unable to find the registered user." and the install fails terminally. Apple enforces one VPP user per (location, managed_apple_id), so blindly re-registering hits a different error (9635). The recovery is two-step:

  1. On 9609, look up the existing user via GET /mdm/v2/users?managedAppleId=…. If Apple has an active record, upsert that clientUserId back into vpp_client_users and retry the associate.
  2. If Apple genuinely has no active user (only Retired entries), register a fresh one via the v1 endpoint and retry.

Each branch logs a distinct WARN so the self-heal is visible in operator dashboards. Only one retry — if the follow-up associate fails, the second error is surfaced.

Test plan

  • make lint-go-incremental — clean
  • go test ./server/mdm/apple/vpp/... ./ee/server/service/... ./server/service/ -run '<targeted>' — all green
  • Manual repro against a local k8s Fleet against Apple's production VPP endpoint:
    • Confirmed the original v2 install left apple_user_id NULL.
    • Confirmed the 9609 path triggers the lookup-then-recover branch after corrupting vpp_client_users.client_user_id and observing the WARN line + restored UUID.
  • Manual install of a personally-installed App Store app on a BYOD-enrolled iPhone, verify the new error message is shown in self-service.
  • Manual install of a VPP app on a managed iOS host — verify "already installed" still routes to verification (no regression in the managed path).

"original_err", err.Error())
}

clientUserID = recoveredClientUserID
@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Codecov Report

❌ Patch coverage is 79.57746% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.83%. Comparing base (83d0673) to head (dae5806).
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
ee/server/service/software_installers.go 73.68% 5 Missing and 5 partials ⚠️
server/service/apple_mdm.go 66.66% 7 Missing and 3 partials ⚠️
server/mdm/apple/vpp/api.go 86.56% 6 Missing and 3 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main   #46108    +/-   ##
========================================
  Coverage   66.82%   66.83%            
========================================
  Files        2754     2754            
  Lines      220138   220244   +106     
  Branches    10905    10905            
========================================
+ Hits       147117   147209    +92     
- Misses      59730    59736     +6     
- Partials    13291    13299     +8     
Flag Coverage Δ
backend 68.64% <79.57%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant