API 401 errors

BriBri210786
New Contributor

I've setup an API role to Read Smart Computer Groups + Read Static Computer Groups but when I try the script (at bottom) following I get this result:- 

Access token obtained successfully.

{

  "httpStatus" : 401,

  "errors" : [ ]

}

I'm fairly new to the API side of things so might be the script is inaccurate. 

My Questions are:-

1) If I go to JAMF_PRO_URL/Api what do I put for username and password (screenshot below)? Is this an account that has access to the Jamf Pro instance or should this be client id / secret or something else? 

BriBri210786_0-1733356225345.png

2) What privileges do you need as a user in Jamf Pro to be able to run these API calls? 

3) Is there something wrong with the script below? If I do echo "$access_token" should it show details or would it be normal to get a response like "Could not extract value..." 

 

For the script below I changed JAMF_PRO_URL to URL for Jamf Pro instance and CLIENT_ID + SECRET to details of the API Client. 

 

 

#!/bin/zsh
baseURL="JAMF_PRO_URL"
client_id="CLIENT_ID"
client_secret="CLIENT_SECRET"
response=$(curl --silent --location \
--request POST "https://$baseURL/api/oauth/token" \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=$client_id" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_secret=$client_secret")
access_token=$(echo "$response" | plutil -extract "access_token" raw -)
if [ -z "$access_token" ]; then
echo "Error: Failed to obtain access token."
echo "Response: $response"
exit 1
else
echo "Access token obtained successfully."
fi
curl -X 'GET' \
'https://JAMF_PRO_URL/api/v1/computer-groups' \
-H 'accept: application/json'

 

 

 

1 ACCEPTED SOLUTION

AJPinto
Esteemed Contributor

1. The credentials you are entering are bad, or do not have access to authenticate Jamf Pro. This method of API access has nothing to do with Client ID's and Secret Keys (API roles and clients) and is just username and password based (User accounts and groups), after you successfully authenticate it will generate a bearer token which the commands will use.

2. You are using User accounts and groups and not API roles and clients, API access matches console access. If a user account can edit a computer record in on the Jamf website, it can also do so in API. If you configure API roles and clients, that is role based and very granular, and all of its access permissions are by roles given to the accounts, but you would not use these accounts with jamfcloud.com/api, and its more focused around application based API access.

3. At a glance you are mixing up authentication methods, the script looks to use Client ID's and Secret Keys which is using API roles and clients, rather than using a bearer token. What you are wanting to do can be made to work, but its best left for once you have the fundamentals down.

 

I recommend sticking to username and password based authentication for API with bearer tokens, and get individual commands working before you try to string together a script. Walk before you run, you are not going to get very far until you can successfully generate a bearer token.

https://developer.jamf.com/jamf-pro/docs/jamf-pro-api-overview

View solution in original post

2 REPLIES 2

AJPinto
Esteemed Contributor

1. The credentials you are entering are bad, or do not have access to authenticate Jamf Pro. This method of API access has nothing to do with Client ID's and Secret Keys (API roles and clients) and is just username and password based (User accounts and groups), after you successfully authenticate it will generate a bearer token which the commands will use.

2. You are using User accounts and groups and not API roles and clients, API access matches console access. If a user account can edit a computer record in on the Jamf website, it can also do so in API. If you configure API roles and clients, that is role based and very granular, and all of its access permissions are by roles given to the accounts, but you would not use these accounts with jamfcloud.com/api, and its more focused around application based API access.

3. At a glance you are mixing up authentication methods, the script looks to use Client ID's and Secret Keys which is using API roles and clients, rather than using a bearer token. What you are wanting to do can be made to work, but its best left for once you have the fundamentals down.

 

I recommend sticking to username and password based authentication for API with bearer tokens, and get individual commands working before you try to string together a script. Walk before you run, you are not going to get very far until you can successfully generate a bearer token.

https://developer.jamf.com/jamf-pro/docs/jamf-pro-api-overview

Chubs
Contributor

You need to add the access token to your curl header:

-H "Authorization: Bearer ${access_token}"



I use a functions to gather my tokens so I can refresh/gather as needed:

########################################################
# API Functions
########################################################

getAccessToken() {
	response=$(curl --silent --location --request POST "${url}/api/oauth/token" \
 	 	--header "Content-Type: application/x-www-form-urlencoded" \
 		--data-urlencode "client_id=${client_id}" \
 		--data-urlencode "grant_type=client_credentials" \
 		--data-urlencode "client_secret=${client_secret}")
 	current_time=$(date +%s)
 	access_token=$(echo "$response" | plutil -extract access_token raw -)
 	token_expires_in=$(echo "$response" | plutil -extract expires_in raw -)
 	token_expiration=$(($current_time + $token_expires_in - 1))
}

checkTokenExpiration() {
 	current_time=$(date +%s)
    if [[ token_expiration -ge current_time ]]
    then
        echo "Token valid until the following time: " "$token_expiration"
    else
        echo "No valid token available, getting new token"
        getAccessToken
    fi
}

invalidateToken() {
	responseCode=$(curl -w "%{http_code}" -H "Authorization: Bearer ${access_token}" $url/api/v1/auth/invalidate-token -X POST -s -o /dev/null)
	if [[ ${responseCode} == 204 ]]
	then
		echo "Token successfully invalidated"
		access_token=""
		token_expiration="0"
	elif [[ ${responseCode} == 401 ]]
	then
		echo "Token already invalid"
	else
		echo "An unknown error occurred invalidating the token"
	fi
}​



________________________________________________

I find your lack of faith disturbing