Automatic Secure Token from Enrollment

dcappelle
New Contributor III

Hey Everyone,

 

I know how secure tokens work, I know how to give them out. I have a particular question about having them automatically enabled without having to log into the account manually on each machine.

 

I have it enabled so that every account can have a secure token, when they login. The issue I'm having, is my Local Administrator account.

I have my management account as JAMFADMIN, and my local administrator is just "administrator". That's the account I use to reimage machines and do maintenance/updates. As we know, M1 machines need to have the account doing updates/OS installs to have a secure token. I have this account being made on Enrollment, so it should get one. The account is on the machine, but if I do a remote command to do an update, the secure token isn't enabled until I physically go to the computer and log into the account. Then it's available.

 

Does anyone know how to make this token appear, without logging in?

If anyone needs any other information, please let me know.

 

Thanks,

Dominic

1 ACCEPTED SOLUTION

I can even share one of the prototype scripts that is up and running in our dev environment and working good so far, please keep in mind that i am not used to expect so the script is still rather noobish. Not sure about sharing the other Versions of the script since this Prototype is the only one that only I worked on and i would not share versions from my Colleges without asking them before.

First of all this script is scoped to every computer that enrols  trough an PreStage Enrollment that is creating one Admin account but is skipping the Account creation in the Setup.
The policy itself is using the Enrollment Complete Trigger, since the first Trigger that every Computer enrolled into Jamf via PreStage will send is this one at the moment it is reaching the login screen.
And so far no User was able to physically login in a few seconds after reaching this screen. If one however would be fast than the script.... well in that case i think he deserves the Token 😱

This script is at  no point elegant or even especially good designed it is just there to get the job done.
We are using the fact that on MacOS the expect language is already installed, if in the future this is changing you may need to consider installing expect in the PreStage Enrollment.
In this one we did not even considered the chance that a bootstraptoken is already installed, so please see it as a Basis to work on. Beside that we will also share some of our Experience on the Community Page of the Berlin Mac Admins: https://berlinmacadmins.github.io/ in the near feature. Alongside the script.

 

#!/usr/bin/expect
#argument number in expect is JAMFArgumentnumber-1
#getting credentials from arguments
set admin [lindex $argv 3]
set pass [lindex $argv 4]

#starting login process
spawn login $admin
#waiting for password question and entering password
expect "Password:"
send -- "$pass\r"
#waiting since logout without a short wait did not worked as i tought.
sleep 1
expect "\r"
# creating and escrowing the bootstraptoken
send --"sudo profiles install -type bootstraptoken"
expect "Password:"
send -- "$pass\r"
expect "Enter the admin user name:"
send -- "$admin\r"
expect "Enter the password for user '$admin':"
send -- "$pass\r"
expect "Bootstrap Token escrowed"
#login out of terminal
send -- "logout\r"
exit

 

View solution in original post

47 REPLIES 47

Tribruin
Valued Contributor II

Whenever the topic of Secure Tokens come up, I refer back to Traveling Tech Guy's blog. He has come great blog posts arounds ST. 

This is a longer discussion of whether your local admin should or should not have an ST, but here is an important callout:

Important: Bootstrap only gives an account a SecureToken when that account is logging in via the LoginWindow (after Bootstrap was enabled). Yes, a login though the login window. Important for the rest of the discussion.

Here is the whole article:

Additional admin with SecureToken, or not? - Travelling Tech Guy

I believe you can also grant a secure token using the sysadminctl command. 

sysadminctl -secureTokenOn <user name> -password <password> (interactive || -adminUser <administrator user name> -adminPassword <administrator password>)

But you would need to know the password of an existing ST user (i.e. the first user.) You could prompt the user for their password via a policy in Jamf to grant the token. 

 

dcappelle
New Contributor III

@Tribruin wrote:

But you would need to know the password of an existing ST user (i.e. the first user.) You could prompt the user for their password via a policy in Jamf to grant the token. 

 


That's half the battle. This is after enrollment, when the computer first turns on, so there wouldn't be an account with a password that I know, that has a token. These are shared machines, so there isn't an account being created through setup assistant. I know how to set tokens.

Tribruin
Valued Contributor II

Can you help me understand your enrollment workflow? You are creating an admin user via PreStage? What about the actual user account? Are you skipping account creation? So, when you get the login page, the only user account is your admin account? Do you then shut the machine off?

 

The admin account created via a PreStage is not granted a Secure Token. As mentioned, to be given a Secure Token, the user must authenticate at the login screen, since there is no other user with a secure token. 

I don't think there is a workflow that will accomplish what you are trying to accomplish (grant a Secure Token without logging on with the Administrator account.) 

dcappelle
New Contributor III

Yeah, that's what I was curious about. I didn't think it was possible, but never hurts to ask.


The admin account gets created via the prestage enrollment. Also on the prestage is my Jamf Connect, so when the computer gets past the automated enrollment, it's immediately ready to log into our Azure services.

mhasman
Valued Contributor

With similar setup, the biggest issue I am facing is service "administrator" account password rotation. Without secure token, there is no possibility /yet/ to change password by Jamf PRO policy 

adefallo
New Contributor II

I HIGHLY recommend Delinea Privilege Manager (formerly Thycotic) for this. We just implemented it and it’s doing our password rotation on our main admin account. The ONLY disadvantage to this is that you must have one admin account that never has a password rotation (so that the account can change other account passwords). This is one we made an incredibly long and complex random password that JAMF deploys as part of pre-stage. The software then automatically rotated the other admin passwords on a scheduled basis. 

Ismere
Contributor

Hi everyone,

a bit late to the discussion i know but maybe my Information can at least help a bit.
What we found out is that for BigSur and Monterey (not tested on Catalina) the first account to login gets the SecureToken even if it is a Terminal login.

Practical that means that Macs are running an expect script that does this Terminal login, right after the enrolment, using the Admin Account that we defined in the PreStage. And while we are logged in we also make sure to create a BootstrapToken to ensure that the Users logging in after us via the Login Screen will get the needed SecureToken.

Doing this will remove the need of a physical login on the computer just to get the SecureToken and Bootstraptoken. It also ensures that the SecureToken is created on an admin account and not on a Non-Admin one.

dcappelle
New Contributor III

Can you explain how you do that?!

I can even share one of the prototype scripts that is up and running in our dev environment and working good so far, please keep in mind that i am not used to expect so the script is still rather noobish. Not sure about sharing the other Versions of the script since this Prototype is the only one that only I worked on and i would not share versions from my Colleges without asking them before.

First of all this script is scoped to every computer that enrols  trough an PreStage Enrollment that is creating one Admin account but is skipping the Account creation in the Setup.
The policy itself is using the Enrollment Complete Trigger, since the first Trigger that every Computer enrolled into Jamf via PreStage will send is this one at the moment it is reaching the login screen.
And so far no User was able to physically login in a few seconds after reaching this screen. If one however would be fast than the script.... well in that case i think he deserves the Token 😱

This script is at  no point elegant or even especially good designed it is just there to get the job done.
We are using the fact that on MacOS the expect language is already installed, if in the future this is changing you may need to consider installing expect in the PreStage Enrollment.
In this one we did not even considered the chance that a bootstraptoken is already installed, so please see it as a Basis to work on. Beside that we will also share some of our Experience on the Community Page of the Berlin Mac Admins: https://berlinmacadmins.github.io/ in the near feature. Alongside the script.

 

#!/usr/bin/expect
#argument number in expect is JAMFArgumentnumber-1
#getting credentials from arguments
set admin [lindex $argv 3]
set pass [lindex $argv 4]

#starting login process
spawn login $admin
#waiting for password question and entering password
expect "Password:"
send -- "$pass\r"
#waiting since logout without a short wait did not worked as i tought.
sleep 1
expect "\r"
# creating and escrowing the bootstraptoken
send --"sudo profiles install -type bootstraptoken"
expect "Password:"
send -- "$pass\r"
expect "Enter the admin user name:"
send -- "$admin\r"
expect "Enter the password for user '$admin':"
send -- "$pass\r"
expect "Bootstrap Token escrowed"
#login out of terminal
send -- "logout\r"
exit

 

dcappelle
New Contributor III

Thank you so much for this!
I'll give something like this a try and I'll let you know what I find out.

dcappelle
New Contributor III

If anyone wants this in one script to run from JAMF, this is what I have figured out.

 

#!/bin/bash

/usr/bin/expect<<EOF
spawn login administrator
expect "Password:"
send -- "<pw>\r"
sleep 5
send -- "logout\r"
expect eof
EOF

exit 0 

 

dcappelle
New Contributor III

This actually worked! Have it run this script right after enrollment. Now my Admin account has a secure Token!! This will save me so much time! Thank you @Ismere 

bcameron
New Contributor III

Has anyone found a solution for Ventura that works. No Pre-Stage user created receives a secureToken any way I try except creating the local user manually then enrolling.

Hi,
did you already tried the script, you can check the details in the History of your policy and can see the terminal responses which may help to identify the problem... in our case the Devices with Ventura worked just fine. But there are some rare cases when the Account created trough Pre-Stage is not getting a UserID (approx. 1-3 devices per 1000 Installations), this results in the Admin account not being usable.
Which in fact means that the login script would need to be improved around catching this problem.
For the amount of Macs we are managing deleting and recreating the Adminaccount trough Jamf Policies was acceptable.
Personally i still want the process to be integrated and automated.

bcameron
New Contributor III

Yes, I tried both scripts. Neither works. I even created a completely new Pre-enroll and added it to that with no luck.

You could check the log of the one that runs in a Policy. Especially the Detailsview in the logs. Normally the script is giving back some information. You can also share this and i can Check it for you. Ommiting every internal information you see.

bcameron
New Contributor III

I finally got it working after I did a ground-up build of a new PreEnroll. I used the original script posted by Ismere.

Thanks everyone for the suggestions.....and thanks Ismere for the script.

bcameron
New Contributor III

Actually, maybe I spoke too soon. On subsequent attempts, it went back to being Disabled again. :(

I will do a little more testing.

In a case where it is not working could you check the UID of the PreStage created Account. Cause our M1 and M2 are working like a Charm beside the ones where the PreStage created Account is not getting any UID.

I am trying to update the Script this or the next week to catch some common errors and at least returning an error to JAMF when the BootstrapToken is not getting created. In Combinantion with 2 Policies to at least automatically delete and recreate Accounts without  any UID, but i can not promise yet that i can do it this week. Fully depends on my workload in the next few days.

bcameron
New Contributor III

I had this running for a couple of weeks. ST was granted to the initial user created by Pre-Enroll (Built 7 machines). This week, nothing is working again. Grrrrrr. This is so frustrating.

Hi bcameron,
I finally had some time to create a new Version of the Script. With one of my Colleagues as the Co-Author since he also wanted to learn some more about expect Scripting.
Since the script is way longer then the old one and has some Prerequisites i just wrote a new Entry for it.
You can find it here: https://community.jamf.com/t5/jamf-pro/automatic-secure-and-bootstraptoken/m-p/292944#M260354
Hopefully this will be of more use then the old one. Since it also includes some Feedback and Errorhandling.
Greetings Ismere

anelson11
New Contributor II

Where do we pass the admin account credentials for the script?

Hi anelson11,
since you run this script from JAMF you can pass the credentials via the JAMF Parameters.
In the old one you just passed the admin account in param 4 and the password in param 5.
In the new one i linked to you will use, additionally, param 6 for api account and param 7 for api account password and change the url site directly in the script since this will not change, in a normal use case.
You can always ask me about the usage or implementation of the script if you need help with it.

anelson11
New Contributor II

Will the older script not work on ventura?

In our Envoirement it worked just fine. The newer one just incorprates an additional Extension Attribute and 2 Policies to give some more feedback and if , on the first try, the account is not working recreating it.
So it more or less just depends on your use case. If you just want to get a secureToken and Bootstraptoken in one try and collect the non working ones in a group afterwards that is ok.
Because at it is right not the old script does not send any exit beside exit 0 reaching its end.
It was the quick and dirty version but i tought it would already help a lot of people.

anelson11
New Contributor II

Weird...For some reason the policy doesn't want to execute after enrollment or at any check-in. I have the policy set up correctly, I think. I even put "*" in front to make sure it executes first but it skips right over it. Thoughts?

What are the Triggers and the Scope you are using?
Our biggest Problem at the beginning was to Scope to a Group that was not filled when the enrollment complete Trigger happend.
If the Policy is not executing at all there should be no log viewable via Jamf.

anelson11
New Contributor II

So, I have a test area at my office with lots of machines, we have a smart group for them. I basically scoped it to that group and excluded all the other machines except the one I am about to enroll. Triggers are check-in and enrollment. I was checking the policy logs of the machine in question and saw that it isn't executing the policy at all. 

Hmmm did you also checked if the Policy is in Scope for the one you are trying it on?
Just go into its Inventory entry and under Management there is a Section for Policies in Scope.
If the Policy is not listed there then your Scope maybe a bit off... Scoping can be tricky from time to time...
But if it is not executing it at all then it normally boils down to Scoping Problems... eventually directly scoping one computer for a pure functionality check is an option at the beginning.

anelson11
New Contributor II

I don't think it is a scoping issue. For every machine I test on, it shows up in policies in scope, just doesn't execute. It's so weird, because it's just a policy with a script. If the policy is in scope, theoretically, that means it's enabled and will be installed at whatever the next trigger is.

Ismere
Contributor

One of ours is looking like this, the maintenance Task is to update the inventory.

Screenshot 2023-06-16 at 13.22.43.png

If it is a script Issue then JAMF would try to execute the Policy and creates a log entry.
paramters for the script is param 4 account and param 5 password

anelson11
New Contributor II

Does it matter if the script runs "before" or "after"?

anelson11
New Contributor II

and mine looks exactly the same, inventory update too.

running as before. since the inventory collection should be the last action. normally for newer systems you would like to use the Bootstrap information from Jamf after it is created.

Just to make sure you are using the Script that is published here or the newer one?

At the moment i am using my workbreaks and freetime to finally open up a git about the scripts i created so far and even creating some variations to make them more suitable for more workflows

anelson11
New Contributor II

I am using the one mention in this thread. But that shouldnt matter as the policy isnt even running. 

that was just me asking out of curiosity for myself...
beside that. do you have any access to the machine? if so you could check the local jamf log of the testing machine under /var/log/jamf.log
For testing issues triggering a check-in via terminal to view the live feedback is also an option.

anelson11
New Contributor II

I mean that would just grant the admin account secure token, no? I see though that might be the only way to diagnose.

yeah that would grant the admin account a secure token, but the script would run non the less. it will still install the bootstraptoken for this device. But for troubleshooting why JAMF is not even running your Policy logging in and verifying the local log on the machine is more or less the only option as long you do not collect the log via script and send it over to another network storage location.

anelson11
New Contributor II

Ok, it seem that the policy doesn't want to run without a secure token user, because I was able to manually execute the policy. It also failed with exit code 1. Mentioned that "bad pattern:  [lindex