How I Reported a Serious Jamf Pro API Bug
Asset Management App
One of the internal tools that I have built at WePay is an Asset Management tool which our IT team uses to manage the lifecycle of employees' MacBook Pro work computers. This service ties together Jamf Pro (for managing Mac computers), Jira (for creating IT Helpdesk issues), our SQL database, our People Portal (for onboarding/offboarding employees), and other things with our business logic. For instance, when an employee is offboarded, the following things automatically kick in for each of their laptop(s):
- Unmanaged in Jamf
- Device locked via Jamf
- Logged in an audit history table
- State changed to
Pending Return
- Jira issue created for IT Helpdesk
- Asset sheet created with PDF, which IT prints out and attaches to the laptop
- Jira issue created for offboarded employee
- Jira issue created for security team
- And many other things which are beyond the scope of this blog or that I cannot talk about...
Jamf Pro API
The Jamf Pro API moved out of beta to production around a year ago, and I discovered and reported a serious bug that could affect a lot of users. For context, Jamf has two API's: the Classic API and the Jamf Pro API. The Classic API uses basic authentication and XML payloads, and the Jamf Pro API uses modern bearer auth token authentication and JSON payloads. As you can probably tell, the Jamf Pro API is a lot newer. In fact, it graduated from beta around a year ago. I had developed on it while it was on beta and after it was out of beta, mainly out of necessity because it had a few features that the Classic API did not support such as the ability to fetch DEP (Apple Device Enrollment Program) computers so that we could load computers that we had purchased from Apple into our tool.
A few months ago, my teammates noticed a problem where Jamf computers that had been offboarded were no longer Filevault disk encrypted. This was a serious security problem because our company data needs to stay protected until the laptop comes back to IT and goes into 30 day hold, before it can be wiped and issued to new employees or e-wasted. I immediately began looking into what the culprit could be. At first, I thought it was the Jamf device lock command which could be causing the problem, but after some isolated tests where only the Jamf device lock command was issued, I deduced that this was not the problem. Next, I checked if it could be a result of unmanaging a computer from Jamf; this also was not the problem. I then noticed that this problem of Jamf computers losing their Filevault encryption was not only when employees were offboarded, but actually when any Jamf computer state changed, which resulted behind the scenes in a name change via the PATCH /computers-inventory-detail/{id} Jamf Pro API request documented here. The JSON payload looks like this:
{
"general": {
"name": "ABC1234-pendingReturn"
}
}
It's the most basic PATCH API request to update a single Jamf computer, and somehow when this was being called it would result in a computer having its Filevault encryption removed.
I immediately reported this to Jamf API Support to double check if I might be doing something wrong. They forwarded the information to their API team, and within a day they responded to me thanking me for reporting this issue because it was indeed a bug. Because this was such a crucial error on a commonly used endpoint, it was marked as critical and deemed high priority.
Stopgap Solution
Now that the Jamf Pro API team knew about the bug, that was great because the problem would be solved. But I did not know how long it would take. Luckily, the solution to get our application running properly was to migrate back to the Jamf Classic API for this API call, by using the PUT /computers/id/{id} call documented here.
API Fix
If you look at the Jamf Pro API changelog here, you can see that with version 10.32.0 a change was made to the PATCH /v1/computers-inventory-detail/{id}
endpoint. Here is a screenshot of the changelog with the relevant line highlighted.
Conclusion
This was a team effort. A member of the Helpdesk team had first discovered this issue, and then discussed it with our Jamf admin. We discussed the issue together, I did testing, and then contacted Jamf Support. The takeaway here is that API's - even from reputable companies like Jamf Pro - can have bugs, and just because an API is in production does not guarantee that it will work properly. As software engineers, we always try to use libraries, API's, and tools that will work properly. But it's important to factor in risk in our system design docs when leveraging external libraries. Luckily, when I wrote the system design doc for our Asset Management app, I had discussed this with the senior software engineer on our team and we knew that it was safe to use the newer Jamf Pro API because we knew that we could always fall back on the Jamf Classic API. In fact, I had first coded the system to use the Jamf Classic API to ensure that it worked, and then upgraded the call to Jamf Pro API because we needed other Pro API features. This was a great learning experience in my software engineering career, and I feel proud to have reached a point in my career where I am not only actively maintaining my team's codebase, but also helping to improve other systems on which we rely.