Jamf Pro API password in extension, any solution?

BCPeteo
Contributor III

Writing a extension script to use the API to get some LDAP info on lastuser.

Even thought API will only have read ability to Jamf LDAP setup the API call will be running daily on every endpoint and I do not want the API password in the script.

Any ideas on how to get around this?

7 REPLIES 7

williamsad
New Contributor III

Run the script in a policy with a frequency you desire but write the value to a plist. You can store this in /Library/Preferences or wherever you want. Then setup the EA to read that value

AJPinto
Honored Contributor III

You will need a more complex of a script that uses a bearer token and performs the keep alive. I would look into a tool that is built to do what you are wanting, as if you can't find one you will be building the tool before this is over.

 

Refresh token (jamf.com)

That's the problem you need to use the API user and password to create the bearer token

 

Edit: You could base64 it and then pass it, but base64 is not security

easyedc
Valued Contributor II

Am I understanding your question?  You want to read your company's LDAP and write to Jamf EAs through the API? If so, it's a little convoluted, but I do it. I do most of the heavy lifting with the password as a variable in a script. 

apiUser="$4"
apiPass="$5"

When you build your policy and add the script, they'd become the first 2 parameter values you can pass. 

Once that's done, have the output of your script write to your EA. Depending on what you're capturing you may have to write it to a text file or a json or something else you can subsequently parse. But adding to the EA is relatively simple. 

EAid=SOME_NUMBER
EA_Value="$scriptoutputgoeshere"
echo "Writing this - $EA_Value"

/usr/bin/curl --header "Authorization: Bearer $token" \
--request PUT \
     --url $jssurl/JSSResource/computers/id/$computerID -H "Content-Type: application/xml" -d "<computer><extension_attributes><extension_attribute><id>${EAid}</id><value>${EA_Value}</value></extension_attribute></extension_attributes></computer>" -X PUT

 I have a similar script that does all this. It has a token for reading some internal AD info that we store in an accessible service and can be read through API. That read data then writes a json locally. The json is parsed and writes to my EAs as needed.  Our laptop turn over is not very active, so I only do this once a month. The thought is passing the user/pass or auth token as a variable reduces who can see it since only a few folks have access to read policies.  There's a few posts about getting a token for your API, so do that as you see fit. Once that's done, there's a little bit of work to get the computerID, instead of the serial, for writing the EA.

computerID=$(curl -X GET "$jssurl/JSSResource/computers/serialnumber/$Serial" -H "Accept: application/xml" -H "Authorization: Bearer $token" 2>/dev/null | xpath -e '/computer/general/id/text()' 2>/dev/null)

echo $computerID

I don't have any concern about writing the output of my AD lookup to the computer locally and then reading it back to my JSS, since all the data being written is about who is using it, and it's their own data. All my scripts are written to use native tools to the OS, I don't install anything remotely (for ex jq is great for parsing json, but it requires additional installs) so some of my scripts have extra work in them. ¯\_(ツ)_/¯  

I may have rambled a bit, but that what works for me.

Thanks for this, I was thinking this way too, to use a policy with encrypted attributes (using encrypted strings) and have the policy script write the file and use an extension script to read it.

There is still a matter of the API call to create the bearer token running on a users machine. I'm not sure how much of a risk it is. API user and password will be decrypted and the POST will need to use those credentials to get the bearer token.

I am kind of surprised there is nothing in a policy automatically generate a bearer token to use for API calls

jamf-42
Valued Contributor II

while some may disagree, the JAMF API is not supposed to be run on the endpoint and I would never do an API call in an EA.. as @williamsad posted..  script via policy, write the value out, collect via EA. 

Yes that sounds like the best way, but again it has its perils  https://macnotes.wordpress.com/2022/02/01/jamf-pro-api-script-security/ 

The only thing to really solve this would be for Jamf to add a policy setting to generate on the fly bearer token (that is generated on the server using an API account user name and password) to be passed to the script. I wouldn't hold my breath though.