Let’s Get Conditional - Jamf and Company Portal.app Registration Deconstructed (Part 1 - Client Side)
This is the second of a multi-part series about the macOS Intune and Azure AD integration for inventory data and Conditional Access with Jamf Pro.
The topic of this post is explaining the macOS device registration process (client side) of the integration performed by an end user to start the inventory data sync and place the key on the device for Conditional Access.
TL;DR: The macOS device runs a Jamf Pro policy that calls Company Portal.app with the -r (registration only flag) that places the WPJ key and then jamfAAD reads that and the created device AAD ID and posts with that ID to Azure along with Jamf Pro data.
Under the hood of the Registration Policy and its order of operations…
In this example we will see the following on screen and in the logs.
They play out in this order:
Device Launches Self Service.app
Executes policy that calls Company Portal.app with the registration flag
User signs into Company Portal.app with Azure AD credentials and Company Portal.app places the WPJ key in the users login.keychain; it also makes an AAD shell record of the given macOS device for later use by Jamf Pro (will be covered in upcoming server side blog post)
User closes Company Portal.app, and jamfAAD does a sign-in via the Jamf Native macOS Connector, and asks to read the users login.keychain to read the WPJ key
The data jamfAAD gathers is sent back to Jamf Pro
When the registration policy is trigged via the Self Service.app a binary called jamfAAD is used. jamfAAD is going to then call Company Portal.app using the specially built -r flag.
Found in /var/log/jamf.log
:
Sun Apr 26 22:06:14 test-mbp jamf[1480]: Executing Policy Register With AAD
In Unified macOS System Logging:
default 2020-04-26 22:06:15.055131 -0500 JamfAAD Launching Company Portal
From Company Portal.log:
2020-04-27 03:07:10.363 VERB com.microsoft.ssp.telemetry TID=10318 AriaTelemetryService.swift: 283 (sendEvent(featureArea:type:eventTitle:duration:result:target:location:resultData:error:context:workflowData:clientRequestId:shouldSanitizeStrings:)) Sending event using aria: OutgoingServiceRequest : {
clientRequestId = "REDACTED";
context = "TenantID:REDACTED";
durationMs = 304;
eventTitle = "Auth_FetchSvcToken";
featureArea = Login;
result = Succeeded;
target = AADWPJToken;
}
2020-04-27 03:07:12.149 VERB com.microsoft.ssp.telemetry TID=10971 AriaTelemetryService.swift: 283 (sendEvent(featureArea:type:eventTitle:duration:result:target:location:resultData:error:context:workflowData:clientRequestId:shouldSanitizeStrings:)) Sending event using aria: OutgoingServiceRequest : {
clientRequestId = "REDACTED";
context = partnerFlow;
durationMs = 2091;
eventTitle = "WPJ_DeviceRegistration";
featureArea = WPJ;
result = Succeeded;
target = "TokenFetchDuration: 305.7299852371216";
}
2020-04-27 03:07:12.156 VERB com.microsoft.ssp.telemetry TID=10971 AriaTelemetryService.swift: 283 (sendEvent(featureArea:type:eventTitle:duration:result:target:location:resultData:error:context:workflowData:clientRequestId:shouldSanitizeStrings:)) Sending event using aria: InAppProcess : {
context = partnerFlow;
durationMs = 2375;
eventTitle = CompleteWPJOperation;
featureArea = WPJ;
result = Succeeded;
}
2020-04-27 03:07:19.995 INFO com.microsoft.ssp.workplaceJoinSdk TID=9811 WorkplaceJoinManager.swift: 845 (workplaceClient(_:logMessage:)) INFO: [2020-04-27 03:07:19 +0000]getRegistrationInformation: Retrieved certificate thumbprint
2020-04-27 03:07:19.996 INFO com.microsoft.ssp.workplaceJoin TID=9811 WorkplaceJoinManager.swift: 54 (cachedWorkPlaceJoinState) Cached workplace join state set to: Optional(__C.WorkPlaceJoinState(rawValue: 2)))
2020-04-27 03:07:19.996 VERB com.microsoft.ssp.telemetry TID=9811 AriaTelemetryService.swift: 283 (sendEvent(featureArea:type:eventTitle:duration:result:target:location:resultData:error:context:workflowData:clientRequestId:shouldSanitizeStrings:)) Sending event using aria: InAppProcess : {
context = partnerFlow;
eventTitle = CompanyPortalExited;
featureArea = General;
result = Succeeded;
resultData = 0;
}
After the Workplace Join completes Company Portal.app will call back to jamfAAD with an exit code. jamfAAD will then run and gather the info of the WPJ key info, UPN, and AAD ID created for the new device record on AAD by Company Portal.app and submit that information to Jamf Pro.
Possible Comapny Portal.app exit codes:
success = 0
defaultError = 1
userAbandoned = 64
registrationError = 65
registrationDeviceCapError = 66
registrationKeychainError = 67
authenticationError = 68
networkError = 69
commandLineError = 70
In Unified macOS System Logging:
default 2020-04-26 22:07:22.174916 -0500 JamfAAD Collecting Azure Active Directory ID
default 2020-04-26 22:07:22.241349 -0500 JamfAAD TID = 11075 ADAL 2.7.12 Mac 10.15.4 [2020-04-27 03:07:22 - UUID-HERE] No cached preferred_network for authority
default 2020-04-26 22:07:22.381583 -0500 JamfAAD Task <UUID-HERE>.<1> received response, status 200 content K
default 2020-04-26 22:08:09.647316 -0500 JamfAAD 0x600000ba4000 commited /Users/intune2/Library/Keychains/login.keychain-db.sb-XX to /Users/bob.lutz/Library/Keychains/login.keychain-db
After the end user allows jamfAAD to access the login.keychain the data is then sent to Jamf Pro
jamfAAD in Unified macOS System Logging:
default 2020-04-26 22:08:09.659507 -0500 JamfAAD AAD ID acquired for macOS user account bob.lutz
info 2020-04-26 23:07:12.496853 -0500 JamfAAD Requesting Azure tenant info from jamf daemon
info 2020-04-26 23:07:12.498259 -0500 JamfAAD creating client
info 2020-04-26 23:07:12.500330 -0500 JamfAAD connecting client