Distributing retail PKG files without repackaging?

New Contributor III

Hi everyone, totally new to JAMF and still working on getting our backend configured.

We're looking to make some basic packages available in self service (Google Chrome, Adobe Reader, etc) and I'm a little confused with the need to repackage them with Composer. Assuming we don't want any custom configuration and the regular old "straight from the vendor" install experience is perfectly acceptable, is there a need to take things like the Google Chrome PKG/DMG file downloaded directly from Google and repackage them with Composer, or can I just straight up publish it via Self Service?


Contributor II

A pkg or dmg that is made in composer is not at all like one that is created by a manufacturer. Usually what is made in Composer is simply going to drop in the file as you have it built in the file structure.

For DMG installs, most of the time you can simply drag that to your applications folder. You can then drag that .app from your applications folder in to composer without taking a snapshot. You can then change your permissions and then create the .pkg as you see fit.

For .pkg installs that come from manufacturers, you typically want to do the snapshot process so that you can determine what exactly the installer does, and customize that to your needs.

Valued Contributor

Someone posted this here. I use it for a few things (like Chrome, Adobe Reader, Grammarly) and make it a Self Service item.


# -------------------------------------------------------------------------------------
# Universal App Installer Script
# -------------------------------------------------------------------------------------
# Automatically download and install nearly any app from a direct download link
# App can be packaged as .dmg, .pkg, or .zip, and have either the .app or a .pkg inside
# -------------------------------------------------------------------------------------
# Created by Ella Hansen on 10/30/2018
# v1.0 - 10/30/2018 - Ella Hansen
# Created script based on Caine Hörr's script for Google Chrome:
# https://www.jamf.com/jamf-nation/discussions/20894
# -------------------------------------------------------------------------------------


# Example: DownloadURL="https://dl.google.com/chrome/mac/stable/googlechrome.dmg"

# -----------------------------------------------------------------------------------


# Create directory /tmp/jamf, continue if directory already exists
mkdir /tmp/jamf || :

# Change directory to /tmp/jamf
cd /tmp/jamf

#Download installer container into /tmp/jamf
# -O downloads file without changing its name
curl $DownloadURL -O -L

# If container is a .dmg:
# Mount installer container
# -nobrowse to hide the mounted .dmg
# -noverify to skip .dmg verification
# -mountpoint to specify mount point
yes | hdiutil attach /tmp/jamf/*.dmg -nobrowse -noverify -mountpoint /tmp/jamf/mount ||
# Else if container is a .pkg
# Run installer package with the boot drive as the destination
installer -pkg /tmp/jamf/*.pkg -target / ||
# Else if container is anything else, presumably a zip file:
# Unzip installer container and place contents into /tmp/jamf/mount, continue on error
unzip /tmp/jamf/* -d /tmp/jamf/mount || :

# If contents is installer .pkg:
# Run installer package with the boot drive as the destination
installer -pkg /tmp/jamf/mount/*.pkg -target / ||
# Else if contents is .app:
# Copy the .app file from the installer container to /Applications
# Preserve all file attributes and ACLs
cp -a /tmp/jamf/mount/*.app /Applications || :

# Unmount the secondary installation folder, continue on error
hdiutil detach /tmp/jamf/mount || :

# Delete the main installation folder
rm -r /tmp/jamf

The only thing you really have to change is $4 under Policy -> Script

New Contributor III

Right, but my point is (to follow the Chrome example), the installer from Google already is the way we see fit. We know what it does and we want it to do exactly that. We don't want to change the initial configuration or anything like that, we just want to make regular old Google Chrome available to the users to install through Self Service as they don't have local root access.

In that case, what is unpacking the whole thing using Composer and then repackaging it accomplishing that I'm not seeing? Seems like I'm just taking a snapshot for the sake of taking a snapshot.

Valued Contributor

If you aren't changing anything you don't need to use Composer. There are some very important things you can learn from Composer (what is actually changing, where certain settings live, et al), but not really necessary for basic pumpkin spice latte apps.

You could run every app through Composer. No one is going to stop you. :)

Valued Contributor

@quip_MDavison you should find that most vendors .pkg installers/updaters are good to go as-is, just rename if you like, upload, deploy, profit. It's easy enough to test, and if the results are not what you want, pivot and turn.

For drag and drop apps like Firefox, yes, Composer is a simple tool to package them up for deployment.

New Contributor III

Thanks, that's what I thought. Just wanted to confirm! We'll definitely be using it for some of the more robust stuff we want to deploy, I just wanted to make sure I wasn't missing anything if we didn't pick apart the couple dozen generic apps we already normally make available!

Honored Contributor

I recommend you look into AutoPKG, you can start by checking out the main repo

I don't recommend any sort of curl script that runs on the client end, there are too many risks and margins of error.


Seconding @tlarkin here – don't run curl as root on your clients (which is what the above script is doing). With apologies to the author, this script is particularly bad because it just tries a bunch of stuff with whatever URL you provide it, which can be extremely dangerous.

Use AutoPkg to package applications using trusted recipes. Your clients download the package from your Jamf server, rather than a third-party server. You won't need to use Composer, and it's no more difficult than running autopkg run local.pkg.GoogleChrome then uploading the package to your Jamf server.

I get the thinking behind "universal installer" scripts like the above. Hey, it's easy, right? Less for you to worry about. Until of course something starts going sideways across your whole fleet and you have very little insight into what's causing it...

Honored Contributor

Just to chime in on some of the risks you take when doing this versus having an app catalog of actual packages:

  • you are going to have a hard time rolling back if you have to from bugs or issues to a previous version
  • There are no logic checks in these workflows that AutoPKG has (things like cert signing verification, SSL verification, integration with say a service like Virus Total, etc)
  • You are automating this on every endpoint, versus a single endpoint. This allows you to control, QA, and build any automation or integration you might need from this starting point
  • There is a lack of logging, or an audit trail
  • Unless the CDN you are pulling from does cert pinning, you are subject to MITM attacks. SSL verification is not cert pinning, there is a difference.
  • You can technically automate your entire fleet to a bad version of an app, what if the download fails half way through, or any other edge case you can think of, there isn't a great way to recover other than just run the script again.

If the desired outcome is to automate end to end packaging to deployment this is possible today with AutoPKG and JSS Importer. Yes, there is definitely an initial cost to get this setup, and yes the initial cost is much higher than a single curl script. However, being able to control things from a single endpoint, having all previous versions in your repo (in case you gotta roll back) and being able to log, send notifications to slack, and all the integration AutoPKG offers, it is by far the better answer. I have done this at my Org and while we have never had an issue yet (knocks on wood), if we did, all I would have to do is flip a bit in a smart group and in one policy and I can roll back my entire fleet back to the known good version of the app.

New Contributor III

For retail apps provided "as it" in selfservice or for apps I need to deeply recompose as well, I only use Composer.

For a retail app provided "as it", I install it on a "source" device and remove all elements but "Applications/<some>.app/*" path.
I make a PKG build (I choose DMG only if I have to FUT/FEU), index it into Jamf Admin and make a policy in the MDM.

I don't have a massive use of Self Service for packaged apps. I prefer to deploy (widly or targeted) them by policy since the parc is aimed to be as managed as possible. A non-documented user choice is always a future issue.

Valued Contributor

All valid points boys, but to be fair, I use smart groups to allow me to test it before I release it to the kids. Obviously you don't want to lose control over your deployments.

These are made to be Self Service installers, not system wide, automated installs. YMMV.

Honored Contributor

Given how common the curl scripts are in the Mac Admin world and how uncommon cert pinning is, if I were an attacker specifically seeking out a company with Mac Admins that use jamf + curl scripts I would definitely be looking at using MITM attacks.