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.

6 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

DaneAbernathy
New Contributor III

I found this thread in my search about trying to connect Jamf to our ticketing system to hopefully be able to pull asset and user info for tickets and it's the only thing I've found so far in searching for scopes and the new client credential connections, so I am hoping you, or someone, may be able to help.

The requirements of the "Generic Oauth 2.0" connection in the ticketing system are:

  • Auth Endpoint
  • Token Endpoint
  • ClientID
  • Client Secret
  • Scope

And it is expecting an auth token and refresh token and I am guessing this just isn't going to work for me, based on what you've posted, and the docs say about what's returned with a token request.

Here are the fields from the ticketing system:

DaneAbernathy_1-1714224782457.png

I just wanted to get a sanity check and see if this connection is possible as every mutation of values that I have tried has just netted 401 errors for invalid credentials.

Any help is greatly appreciated.

Thanks!

 

rstasel
Valued Contributor

@DaneAbernathy what ticketing system? do you have a link to their documentation on jamf integration?

DaneAbernathy
New Contributor III

TeamDynamix, there's not documented direct integration.

They have a "Generic Oauth2.0" option for selecting the auth type when adding an integration, the others are Microsoft, etc., and I have no way of modifying the fields. 

I was trying to see if I could square peg/round hole it since most of the fields lined up, but I'm thinking there's no way since when you request a token, there's no Scope in the request header options, you only get the scope in the response from Jamf Pro.

rstasel
Valued Contributor

We use TDX ourselves. =) 

 

Right now, we use powershell to dump out of Jamf into a csv and then use the TDX Asset Importer tool (using ODBC) to import into TDX nightly. Works well, but not sure I'd do it that way if I had to do it again. This is also how I get our assets out of MECM into TDX. 

 

Do you have access to iPaaS? They have a built in connector for Jamf to import assets. 

Otherwise you have to roll your own (like I have above). 

There's also: https://github.com/keller4/TeamDynamix-PowerShell but while I know Brian Keller, I never went down this road since what we had worked. I think longer term I'll likely switch over to iPaaS. 

If you need help figuring out custom integration, happy to help.