Skip to main content
Jamf Nation, hosted by Jamf, is a knowledgeable community of Apple-focused admins and Jamf users. Join us in person at the ninth annual Jamf Nation User Conference (JNUC) this November for three days of learning, laughter and IT love.

Customizing Jamf Connect Login deployment packages with Composer

Prerequisites:
- Obtain an Installer Certificate from Apple. PreStage deployment packages must be signed to be properly installed.
- You've got your own Jamf Pro server, and you've created a special Prestage Enrollment for your Jamf Connect.
- You've created a Smart Device Group for all devices coming out of that Prestage Enrollment.
- You've got the latest packages from https://www.jamf.com/jamf-nation/articles/610/deploying-jamf-connect

Using Composer to Customize the Jamf Connect Login Package:
Grab the JamfConnectLogin-x.x.x.pkg file from the JamfConnect.dmg disk image linked above. (I'm assuming you know that X means whatever the latest version number is.) Drag and drop that into Composer and Convert to Source.

Permissions:
When you import the package and Convert to Source in Composer, sometimes permissions may be incorrect. This will break the package. You need to apply:
- root:wheel ownership - 755 read / write / execute permissions (aka RWX for root, R for group and everyone) - /usr/local/bin/authchanger and the /Library/Security/SecurityAgentPlugins/JamfConnectLogin.bundle
- root:wheel ownership - 444 read / write / execute permissions (aka R for root, group, and everyone) - /usr/local/lib/pam/pam_saml.so.2



Pick the /Library/Security/SecurityAgentPlugins/JamfConnectLogin.bundle and apply permissions / mode / to all items enclosed in that bundle.

NOTE: If you deploy the package and at the login issue get nothing but a black screen forever and ever, you have a permissions issue with the package.

While we're here, we can add additional files to the package. This could be branding files for the background and logo shown at login. It could be a script you want to run post-authentication and login. Try to keep the package SMALL to avoid users wondering why their machine is taking so long to set up.

Changing the postinstall script:
By default, the package will change the login mechanism to a plain OIDC login with no EULA, no Notify, no post install mechanism. We can change that.

#!/bin/bash

# Post Install script for Jamf Connect Login OIDC

# Start the preinstallation process.

logger "Jamf Connect Login Post Install Script"

logger "Touch a file to prevent the FV passthrough from engaging on first boot"
/usr/bin/touch /tmp/.jclrun

logger "Adding the default right to the authorization db"

# HERE's the real big change.  We're:
# -reset : RESETs the login mechanism back to an Apple default setup.
# -OIDC : We're telling the system to use the OIDC method for OpenID logins.  You could also use -Okta here for your Okta workflows
# -preAuth : Before we get out of Setup, let's run some custom code -
#   JamfConnectLogin:EULA - Make a user accept a EULA before they get to the main screen.  Useful for lab computers too!
#   JamfConnectLogin:RunScript,privileged - Run a script after they get past the EULA - The script is located in the preference
        tagged ScriptPath and ScriptArgs if you wanted to pass some variables to it.
#   JamfConnectLogin:Notify - Let's show a progress screen while the computer is doing some setup for the first time!

# for Azure
/usr/local/bin/authchanger -reset -OIDC -preAuth JamfConnectLogin:EULA JamfConnectLogin:RunScript,privileged JamfConnectLogin:Notify
# for Okta
# /usr/local/bin/authchanger -reset -Okta -preAuth JamfConnectLogin:EULA JamfConnectLogin:RunScript,privileged JamfConnectLogin:Notify

logger "Jamf Connect Login post install completed"

To get a deep dive into the LoginWindow mechanics, be sure to check https://docs.jamf.com/jamf-connect/1.0.0/login/administrator-guide/loginwindow_Mechanics.html (URL may change as software updates, change to the appropriate build number in the URL) The important pieces are changing the postinstall script to run:

/usr/local/bin/authchanger -reset -OIDC -preAuth JamfConnectLogin:RunScript,privileged JamfConnectLogin:Notify

This turns on the login window to run a script after the user authenticates which can be used to call Jamf Pro policies, run some installer scripts, or put some cute setup messages on the screen. DEPNotify is out of the scope of this document, but you can read more about it on Joel's GitHub page.

Adding a Post-Login Script:
So now that we can customize the package, and we've changed the authchanger to use EULA, Notify, and RunScript, we need a script. In this case, we've got something super simple - make Notify a bit pretty while we wait until we're sure the Jamf Pro binary is on the machine, then toss control to Jamf Pro by calling a custom event - in this case, JamfConnectLoginInstalled

#!/bin/bash

# jamf_dep.sh - a script to deploy Jamf Connect Login and Jamf Connect Verify
# with a prestage enrollment package.
# — SRABBITT January 25, 2019 9:01 AM

JAMFBIN="/usr/local/bin/jamf"

# Set the Main Title at the top of the window
echo "Command: MainTitle: Welcome to Jamf Connect!" >> /var/tmp/depnotify.log
echo "Command: MainText: Welcome to your new Mac.\\nSit tight as we do some basic setup to get you ready for success.\\nYou can see the status of the setup on the progress bar below." >> /var/tmp/depnotify.log

echo "Status: Installing Jamf" >> /var/tmp/depnotify.log

# Wait until the Jamf Binary is fully downloaded
echo $JAMFBIN
until [ -f $JAMFBIN ]
do
    echo "Waiting on Jamf" >> /tmp/output.txt
    sleep 2
done

echo "Jamf Installed" >> /tmp/output.txt

echo "Status: Passing command and control to Jamf Pro" >> /var/tmp/depnotify.log

$JAMFBIN policy -event JamfConnectLoginInstalled

Drop that script into the package in composer, take note of the path to the script. Make sure she's got 755 permissions and owned by root:wheel.
The power here is now everything is in Jamf Pro - we don't need to modify scripts, packages, mess with settings... From this point forward, you can create and call policies just like you know and love.

Create a configuration profile with custom settings:
Once you've got your script, you need to tell Jamf Connect Login that there's a script to run. Let's push a configuration profile with a Custom Settings payload for com.jamf.connect.login scoped to the smart group for everyone coming in through this Prestage. Using your preferred plist creating tool (I personally like Xcode because it's free and who doesn't like a 12 GB text editor).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Description</key>
        <string>Jamf Connect Login Settings</string>
        <key>OIDCClientID</key>
        <string>6601f869-2980-4083-8855-whatever</string>
        <key>OIDCProvider</key>
        <string>Azure</string>
        <key>OIDCROPGID</key>
        <string>6601f869-2980-4083-8855-whatever</string>
        <key>OIDCRedirectURI</key>
        <string>https://127.0.0.1/jamfconnect</string>
        <key>PayloadIdentifier</key>
        <string>com.jamf.connect.login</string>
        <key>ScriptPath</key>
        <string>/usr/local/bin/jamf_dep.sh</string>
</dict>
</plist>

Please replace OIDCClientID and OIDCROPGID with the right information for your application key, either Okta/Azure/whatever. If I get word from support that someone has "whatever" in their key, I will be very disappointed in you.

Note we added a key called ScriptPath - this is the path to the script that will be run AFTER the user has authenticated with their OIDC credentials, BEFORE the SetupAssistant is completed and AFTER the Notify screen has popped up on the screen.

Putting it all together:
Upload your new package to Jamf Pro and add the Enrollment Package payload to your Prestage Enrollment. Tada. You now have a script that hangs on the Notify screen forever and never goes to Finder.

What did I do wrong?

Nothing. Now it's up to you to use Jamf Pro to run a policy at custom event JamfConnectLoginInstalled. You could use this for your zero touch workflow, installing packages, whatever you would do to a machine before handing it to a user. Or you can use it to run a command -

echo "Command: Quit" >> /var/tmp/depnotify.log

That closes the Notify mechanism and continues to Finder on your freshly set up new Mac.

Like Comment
Order by:
SOLVED Posted: by cwilsonncaa

I appreciate your post. I have been attempting this deployment to no avail. Jamf Connect executes as it should, but my Notify script is not. There appears to be a default built-in Notify that is running instead of the script I have packaged with Jamf Connect and set in my PLIST> Any thoughts on why that would be happening?

Like
SOLVED Posted: by marklamont

personally rather than repackage jamfconnect I just drop it in my own wrapper package, meaning I don't have to mess around with it each time it's updated, I just update the wrapper. Less chance of any issues.

I also deploy the graphic(s) for using with Jamf Connect Notify in here.
then in the post install script I install JC, setup initial notify values then sort out the login window;

# install Jamf Connect
installer -pkg "/var/tmp/JamfConnectLogin-1.1.2.pkg" -target /
# set initial notify values
/usr/local/bin/authchanger -reset -preLogin JamfConnectLogin:Notify
/bin/echo "Command: MainTitle: Configuring your Mac..."  >> /var/tmp/depnotify.log
/bin/echo "Command: MainText: Configuring your Mac for use in MyOrg.\n\nThis won't take long and you don't need to do anything." >> /var/tmp/depnotify.log
/bin/echo "Command: Image: "/Library/Management/MyOrg/graphics/myorg-tr.png"" >> /var/tmp/depnotify.log
/bin/echo "Status: Please wait..." >> /var/tmp/depnotify.log

# Wait for the setup assistant to complete before continuing
log "Waiting for Setup Assistant to complete..."
loggedInUser=$(/usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | /usr/bin/awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}     ')
while [[ "$loggedInUser" == "_mbsetupuser" ]]; do
    /bin/sleep 5
    loggedInUser=$(/usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | /usr/bin/awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}     ')
done

# switch login window
killall loginwindow

once the installs are done you can switch login mechanisms back to either JC or default as required

Like
SOLVED Posted: by cwilsonncaa

Thanks for your post. So I must say I feel like an idiot. The issue stemmed from me signing the Enrollment Package that I built with Composer.

The difference is, I have been using a script using the DEPNotify.app with a fully customized DEPNotify Starter script. I like the it runs after the 'Choose Your Look" from Setup Assistant. So choosing Dark Mode, modifies the Notify window appropriately. I have yet to test with the Jamf Connect Login, built-in Notify mechanism.

Like
SOLVED Posted: by hdsreid

In the past I was using a DEPNotify starter script with the app like @cwilsonncaa I have been playing with this new Notify mechanism, and I prefer having all of the packages/scripts/config in one policy as opposed to calling an array of policies. However I cannot find a way to get any kind of status indicator using the Notify mechanism. It just says passing control over to Jamf and the progress bar never moves. Is there anyway to feed the Jamf log updates to the Notify mechanism? This was possible with DEPNotify if you ran it with a -jamf argument

Like
SOLVED Posted: by cwilsonncaa

@hdsreid The Jamf Connect Login Notify mechanism is not as built out as DEPNotify, yet. For example, with DEPNotify, I have user input for device name and asset tag registration and the JCL notify mech does not have user input available.

It also seems the Notify window within the JCL notify mechanism is not as visual balanced when it comes to graphics, may just be me though.

Like