See part 1, if you want general information on how to implement 802.1X device certificates with Jamf via the ACME protocol.
Our whole workflow does, what it should do, right? Not quite, the renewal process of the certificates is not configurable. But Jamf did just that with the release of 11.19.0 of Jamf Pro.
Renewal of certificates
Now, it is possible to set a renewal date relative to the expiry date!
As our certificates are valid for 90 days, we chose 30 days until expiry as a good starting point. It is long enough, so that vacations or business trips don’t end with an expired certificate.
Screenshot
Change the value from never to the desired interval e.g. 30 days.
Further thoughts about the whole ACME workflow
A revocation procedure would be nice. This might be useful, when a device gets compromised or stolen. Sadly, step-ca does not support a certificate-revocation-list, but certificates can be revoked manually. See here for further details.
Instead of deploying a completely new root-ca, maybe an existing one can be used as a trust anchor and our intermediate-ca can be signed by that? There is also documentation available for that case.
Our iPads can be managed the same way, just a different webhook is needed.
What about signing certificates for Android or Windows devices? They can’t use the device attestation protocol with Apple’s servers. Android devices may come into Jamf one day, our active directory for the Windows devices could be deprecated, once Microsoft chose to do that.
At work, our Windows computers are bound to AD, they use the AD-integrated PKI to generate device certificates. These certificates are then utilized to get 802.1X authenticated network access, both wired and Wi-Fi.
Our Macs are not bound to AD, but managed with Jamf Pro as our MDM system. In order to also bring the Macs into the network, we had to prepare a few things:
Set up a separate certificate authority (CA), at best on premise and also without additional costs.
Chose a protocol for certificate creation, SCEP or ACME.
Build a configuration profile for Jamf, so the Macs get certificates and also renewals.
Integrate our new CA into our network tool (Cisco ISE)
Our options for free, open source and locally deployable CA’s are quite limited, also the support for Managed-Device-Attestation (MDA) from Apple was desired. This led us to smallstep’s step-ca in conjunction with the Step Posture Connector and ACME as the protocol that supports MDA.
1. The CA
Let’s start with the setup of step-ca on an Ubuntu server. The firewall has to allow Port 443 for all the jamf servers, and for the company network, so the Macs can also reach it. Additional documentation from smallstep is available here:
… ✔ Deployment Type: Standalone What would you like to name your new PKI? ✔ (e.g. Smallstep): OurTestCA What DNS names or IP addresses will clients use to reach your CA? ✔ (e.g. ca.example.com[,10.1.2.3,etc.]): catest.domain.name What IP and port will your new CA bind to? (:443 will bind to 0.0.0.0:443) ✔ (e.g. :443 or 127.0.0.1:443): :443 What would you like to name the CA’s first provisioner? ✔ (e.g. you@smallstep.com): your.address@domain.name ✔ [leave empty and we’ll generate one]: ✔ Password: ThisIsATopSecretRootPasswordExample
Take good care of the newly created root password!
Now, let’s move the CA to /etc/step-ca and create a daemon to start it automatically. See this guide for it. The root password should now be in /etc/step-ca/password.txt
Best practice for additional security is to change the password for the intermediate certificate, as it is used to sign our device certificates, and it then differs from your root certificates‘ password. See also this guide.
The CA on its own is now ready to use, but for signing device certificates, we need a template. You can use this example for it. The file should be here: /etc/step-ca/templates/certs/x509/leaf.tpl It must also be added to the ca.json configuration.
We should also switch from file-based configuration to a database by enabling the remote provisioner management feature.
2. The Step Posture Connector
The final step for the CA setup is the creation of a webhook. It is later used by the Step Posture Connector to enable the CA to talk to Jamf and Apple.
step ca provisioner webhook add acme-da step-posture-connector --url https://localhost:9443/webhook/device-attest?mode=computer
✔ CA Configuration: /etc/step-ca/config/ca.json No admin credentials found. You must login to execute admin commands. ✔ Please enter admin name/subject (e.g., name@example.com): step ✔ Provisioner: your.address@domain.name (JWK) Please enter the password to decrypt the provisioner key: Webhook ID: 5022a074-2b05-4n87-someMoreCharacters Secret: ThisIsATopSecretWebhookSecretExample
As the Connector runs on the same server, we use localhost:9443 as URL. For Jamf Pro, we have to select the device type, as mobiles are handled differently as computers.
Take a note of the Webhook-ID and the Secret, both are needed later.
We should change the expiration period of the certificates, as in default they last only 24 hours. We chose 90 days => 2160 hours.
step ca provisioner update acme-da --x509-min-dur 20m --x509-default-dur 2160h
Our CA uses the binary for Step Posture Connector, not the Docker container. As it is a standard Linux server, we took the amd64 file. It is then copied to /srv/www/htdocs on the server.
Also create a /srv/www/htdocs/ssl directory for the TLS certificates. Now we can use our CA to create the TLS certificates:
step ca certificate localhost server.pem server.key
# copy these to /srv/www/htdocs/ssl
cp server.pem /srv/www/htdocs/ssl/server.pem
cp server.key /srv/www/htdocs/ssl/server.key
# also copy the intermediate cert
cp /etc/step-ca/certs/intermediate_ca.crt /srv/www/htdocs/ssl/ca.pem
Since this certificate expires regularly, it has to be renewed, at best in a cronjob:
step ca renew --force /srv/www/htdocs/ssl/server.pem /srv/www/htdocs/ssl/server.key
We need a Jamf API role for the Connector, see also here. Take a note of the Jamf Client ID and Jamf Client Secret.
All these go into the .env configuration file in /srv/www/htdocs/, see also here.
Let’s start the connector and see, if everything is fine:
Everything is fine? Then create a cronjob and start the Connector @reboot and in background. Consider running the Connector as a normal user, not as root.
3. Jamf Configuration Profiles
Now to the fun part. Create a Jamf configuration profile that contains your Root- and Intermediate Certificates (and also the certificate the network infrastructure uses), so the Macs trust your newly created CA.
Screenshot
The real fun starts now. Create a Jamf configuration profile with the ACME Payload, the certificate the network infrastructure uses and network configuration payload, all in one profile.
Screenshot
Let’s take a look at the details. The ACME payload sets the step-ca server, the encryption details, and enables attestation via MDA. The certificate’s Common Name (CN) is set to the serial number of the Mac, so we use the variable $SERIALNUMBER twice.
Screenshot
The Network payload uses the just configured ACME certificate and also the additional certificate for trusting our Cisco ISE. We use EAP-TLS.
Screenshot
The trust settings can be seen here:
Screenshot
When these configuration profiles are deployed, the Macs then get a certificate.
Screenshot
The sequence of the certificate generation with ACME protocol can be seen in this diagram. It shows, how all the components work together.
Sequence diagram of certificate generation with ACME.
The certificates are valid for 90 days, they are automatically renewed, when the Macs are a part of the companies network, e.g. Wi-Fi or LAN on premise or via VPN.
4. Network access
Our Cisco ISE needed the Root- and Intermediate-certificates and imported them.
When a Mac now connects to a network port, it shows the device certificate, the ISE matches the issuer of the certificate with the ones it imported before and if everything checks out, the ISE grants network access to a special, 802.1X protected subnet and the Mac gets an IP address.
That’s it.
5. Caveats
It works fine with ARM Macs, with Intel Macs we’ve had some issues. The MDA has to be deactivated, thus only Intel Macs with T2 chip could possibly work, older would ones definitely not.
Our T2 Macs failed to get a certificate, but they are going to be replaced anyway.
Update 01.08.2025: See part 2 for further configuration of the renewal process.