BrysonTyrrell
Contributor II

This post was originally posted to my personal blog, which you can find by following this link.

With Jamf Pro 10.49 admins can now use OAuth client credentials flow for authenticating to the product's APIs.

The documentation for the new API Roles and Clients can be found here. The implementation is straightforward:

  1. Go to Settings > System > API Roles and Clients
  2. Create an API Role
  3. Select all of the applicable Jamf Pro API role privileges it should grant.
  4. Create an API Client.
  5. Select one or more API Roles to assign to it.
  6. Enable the API Client.
  7. Generate the Client Secret.

You can now use the client ID and secret to obtain access tokens. This shell example below is taken from Jamf's developer docs.

curl --request POST "${url}/api/oauth/token" \
    --header "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "grant_type=client_credentials" \
    --data-urlencode "client_id=${client_id}" \
    --data-urlencode "client_secret=${client_secret}"

API Client access tokens have different claims than those returned using user-based basic authentication.

{
  "sub": "55ed202f-371c-41aa-9dc5-c63d6a1f6b3c",
  "aud": "55ed202f-371c-41aa-9dc5-c63d6a1f6b3c",
  "nbf": 1692646434,
  "token-uuid": "eaa92ecb-644f-4a8a-8591-6d6f08f50288",
  "subject-type": "REGISTERED_CLIENT_ID",
  "authentication-type": "CLIENT_CREDENTIALS",
  "scope": [
    "api-role:2"
  ],
  "iss": "http://<redacted>.jamfcloud.com",
  "exp": 1692646494,
  "iat": 1692646434
}

Note that the scope claim contains api-role:2 as the value. Jamf Pro is referencing API Roles by their database IDs and not their name or other identifier. Each assigned roles is represented using the same api-role:ID scheme. When the server validates the token it is querying for API Roles using the IDs found in the scope and applying those privileges.

Role assignments are cumulative. The API Client will have the sum of all API privileges across all of the assigned roles.

This means that changing API Role assignments on an API Client is a scope change.

In Jamf's implementation of client credentials flow, the scope change requires generating a new client secret for the assignment change to take effect. Until this happens the role assignments (scope) at the time the secret was generated will continue to be returned.

Conversely, changing the privileges assigned to an API Role takes effect immediately and do not require generating a new client secret for API Clients that are assigned those the role.

I would recommend that admins adopt a 1:1 relationship of API Role to API Client and not attempt to re-use roles across clients. Otherwise, you may find yourself in a headache situation where you can't update your client's role assignments without interruption.

2 Comments
rstasel
Valued Contributor

Thanks for sharing this. I've got a ticket with Jamf requesting they update their documentation to reflect this. Thought I was going crazy looking at API permissions info, etc. 

Update: 

Have opened a ticket on this. Waited over 24 hours just to make sure there's not some re-eval that happens, same result. 

Entirely defeaters the purpose of breaking up Roles and Clients when it has to be a 1:1 relationship. =(

rstasel
Valued Contributor

Got confirmation from Support this is the expected behavior. =(

Have filed an idea here: https://ideas.jamf.com/ideas/JN-I-28051

About the Author
Enterprise Device Management Administrator