From c9803c2a8f691c230b041721a4ad2868ee3082c5 Mon Sep 17 00:00:00 2001 From: Tim Lee Date: Fri, 10 Jul 2026 16:37:50 -0600 Subject: [PATCH] Docs: non-proxied cert renewal (#45695) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Related issue:** Resolves #44348 **Base branch:** `docs-v4.86.0` (not `main`) per the docs release process. ## What this PR does Updates four customer-facing guides and adds a release-notes entry for Phase 2's opt-in cert renewal feature (shipped via #45696). Frames the marker as an opt-in enhancement: profiles without it continue to work as in 4.85; profiles with it activate auto-renewal. | Guide | Change | |-------|--------| | `connect-end-user-to-wifi-with-certificate.md` | Migrated 11 legacy `\$FLEET_VAR_SCEP_RENEWAL_ID` refs to the preferred name; added back-compat callout. | | `okta-conditional-access-integration.md` | Removed "Automatic renewal coming soon" line; added one-time upgrade-redeploy callout for existing customers. | | `enable-okta-verify-on-macOS-with-configuration-profile.md` | Added marker to example profile OU; added opt-in note and CA-side OU-preservation verification step. Coordinated with the earlier example-profile update from #43293 already on `docs-v4.86.0`. | | `enable-okta-verify-on-windows-using-a-scep-configuration-profile.md` | Replaced manual-redeployment narrative with auto-renewal guidance. Kept the policy-based expiry-monitoring SQL as an optional safeguard. | Release-notes entry (`changes/40639-non-proxied-cert-renewal`) consolidates Phase 2 customer-visible behavior in three bullets. ## Dependencies The Conditional Access guide's "new setups: no extra action needed" framing assumes #45662 (the Fleet-side template marker addition) has landed — it has, merged into the feature branch and onward into main via #45696. # Checklist for submitter - [x] Changes file added for user-visible changes ## Testing - [x] Doc review only — no code changes ## Summary by CodeRabbit * **New Features** * Automatic certificate renewal is now supported for SCEP and ACME certificates from external certificate authorities, enabled by default for new deployments with an opt-in path for existing customers * macOS devices with ACME-bearing configuration profiles will now surface hardware-bound certificates in device vitals --------- Co-authored-by: Rachael Shaw Co-authored-by: Marko Lisica <83164494+marko-lisica@users.noreply.github.com> Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com> Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> Co-authored-by: melpike <79950145+melpike@users.noreply.github.com> Co-authored-by: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Co-authored-by: Jordan Montgomery Co-authored-by: Jonathan Katz <44128041+jkatz01@users.noreply.github.com> Co-authored-by: Victor Lyuboslavsky <2685025+getvictor@users.noreply.github.com> Co-authored-by: Magnus Jensen Co-authored-by: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Co-authored-by: Scott Gress --- articles/apple-mdm-setup.md | 18 +++++++++++-- ...nnect-end-user-to-wifi-with-certificate.md | 22 ++++++++-------- ...ify-on-macOS-with-configuration-profile.md | 16 +++++++----- ...dows-using-a-scep-configuration-profile.md | 26 ++++++++++++------- articles/lock-wipe-hosts.md | 2 ++ .../okta-conditional-access-integration.md | 2 ++ changes/40639-non-proxied-cert-renewal | 3 +++ changes/42827-macos-mdm-certificate-ingestion | 1 + docs/REST API/rest-api.md | 6 ++--- 9 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 changes/40639-non-proxied-cert-renewal create mode 100644 changes/42827-macos-mdm-certificate-ingestion diff --git a/articles/apple-mdm-setup.md b/articles/apple-mdm-setup.md index 54c4e0a134..a6838fcc9f 100644 --- a/articles/apple-mdm-setup.md +++ b/articles/apple-mdm-setup.md @@ -39,6 +39,19 @@ How to connect Fleet to APNs: Connect Fleet to your AB to allow automatic enrollment for company-owned and [Account-driven User Enrollment](https://fleetdm.com/guides/enroll-personal-byod-ios-ipad-hosts-with-managed-apple-account) for personal (BYOD) macOS, iOS, and iPadOS hosts. +### Re-enrolling AB hosts + +When an AB host re-enrolls in Fleet (e.g., after a wipe or OS reinstall), Fleet automatically: + - Cancels pending MDM commands, script runs, and software installs + - Clears completed commands, scripts, and software from the previous enrollment + - Resets host labels + +This means you **do not need to delete** an AB host from Fleet before re-enrolling it. Fleet handles clearing stale state automatically. + +> This automatic state clearing does not apply to hosts undergoing AB MDM migration. During migration, the host's existing state (labels, pending activity) is preserved to ensure a seamless transition from your previous MDM solution. + +### To connect Fleet to AB, you have to add an AB token to Fleet. To add an AB token: + How to connect Fleet to AB: 1. In Fleet, navigate to the **Settings > Integrations > MDM** page. @@ -249,11 +262,12 @@ When an AB host re-enrolls in Fleet (e.g., after a wipe or OS reinstall), Fleet - Clears completed commands, scripts, and software from the previous enrollment - Resets host labels -This means you **do not need to delete** an AB host from Fleet before -re-enrolling it. Fleet handles clearing stale state automatically. +This means you **do not need to delete** an AB host from Fleet before re-enrolling it. Fleet handles clearing stale state automatically. > This automatic state clearing does not apply to hosts undergoing AB MDM migration. During migration, the host's existing state (labels, pending activity) is preserved to ensure a seamless transition from your previous MDM solution. +> For AB hosts, you do not need to delete the host from Fleet before re-enrolling. Fleet automatically clears pending and completed commands, scripts, software installs, and labels when the host re-enrolls. See [Re-enrolling AB hosts](#re-enrolling-ab-hosts). + diff --git a/articles/connect-end-user-to-wifi-with-certificate.md b/articles/connect-end-user-to-wifi-with-certificate.md index 80abf1218b..08e8b91d76 100644 --- a/articles/connect-end-user-to-wifi-with-certificate.md +++ b/articles/connect-end-user-to-wifi-with-certificate.md @@ -42,7 +42,7 @@ We'll deploy a certificate with a dynamic SCEP challenge. To deploy certificates ### Step 3: Add SCEP configuration profile to Fleet -1. Create a [configuration profile](https://fleetdm.com/guides/custom-os-settings) with the SCEP payload. In the profile, for `Challenge`, use `$FLEET_VAR_NDES_SCEP_CHALLENGE`. For `URL`, use `$FLEET_VAR_NDES_SCEP_PROXY_URL`, and make sure to add `$FLEET_VAR_SCEP_RENEWAL_ID` to `OU`. +1. Create a [configuration profile](https://fleetdm.com/guides/custom-os-settings) with the SCEP payload. In the profile, for `Challenge`, use `$FLEET_VAR_NDES_SCEP_CHALLENGE`. For `URL`, use `$FLEET_VAR_NDES_SCEP_PROXY_URL`, and make sure to add `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` to `OU`. 2. If you want your certificates to be unique to each host, update the `Subject`. For example, you can use `$FLEET_VAR_HOST_END_USER_EMAIL_IDP`. You can also use any of the [supported variables](https://fleetdm.com/guides/fleet-variables). @@ -224,7 +224,7 @@ When saving the configuration, Fleet will attempt to connect to the SCEP server ### Step 3: Add SCEP configuration profile to Fleet -1. Create a [configuration profile](https://fleetdm.com/guides/custom-os-settings) with the SCEP payload. In the profile, for `Challenge`, use `$FLEET_VAR_NDES_SCEP_CHALLENGE`. For `URL`, use `$FLEET_VAR_NDES_SCEP_PROXY_URL`, and make sure to add `$FLEET_VAR_SCEP_RENEWAL_ID` to `OU`. +1. Create a [configuration profile](https://fleetdm.com/guides/custom-os-settings) with the SCEP payload. In the profile, for `Challenge`, use `$FLEET_VAR_NDES_SCEP_CHALLENGE`. For `URL`, use `$FLEET_VAR_NDES_SCEP_PROXY_URL`, and make sure to add `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` to `OU`. 2. If you want your certificates to be unique to each host, update the `Subject`. For example, you can use `$FLEET_VAR_HOST_END_USER_EMAIL_IDP`. You can use [Fleet's host variables](https://fleetdm.com/guides/fleet-variables) such as `$FLEET_VAR_HOST_HARDWARE_SERIAL`. For Apple hosts, you can also use any of the [supported variables](https://fleetdm.com/docs/configuration/yaml-files#variables).. @@ -270,7 +270,7 @@ When the profile is delivered to your hosts, Fleet will replace the variables. I OU - $FLEET_VAR_SCEP_RENEWAL_ID + $FLEET_VAR_CERTIFICATE_RENEWAL_ID @@ -352,7 +352,7 @@ You can add any other options listed under Device/SCEP in the [Microsoft ClientC chr - CN=$FLEET_VAR_HOST_HARDWARE_SERIAL NDES Device Cert,OU=$FLEET_VAR_SCEP_RENEWAL_ID + CN=$FLEET_VAR_HOST_HARDWARE_SERIAL NDES Device Cert,OU=$FLEET_VAR_CERTIFICATE_RENEWAL_ID @@ -456,7 +456,7 @@ Currently, using the Smallstep-Jamf connector is the best practice. Fleet is tes 1. Create a [configuration profile](https://fleetdm.com/guides/custom-os-settings) with the SCEP payload. - For `Challenge`, use `$FLEET_VAR_SMALLSTEP_SCEP_CHALLENGE_{CA_NAME}`. - - For `URL`, use `$FLEET_VAR_SMALLSTEP_SCEP_PROXY_URL_{CA_NAME}`, and make sure to add `$FLEET_VAR_SCEP_RENEWAL_ID` to `OU`. + - For `URL`, use `$FLEET_VAR_SMALLSTEP_SCEP_PROXY_URL_{CA_NAME}`, and make sure to add `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` to `OU`. 2. Replace the `{CA_NAME}` with the name you created in step 2. For example, if the name of the CA is "WIFI_AUTHENTICATION", the variables will look like this: `$FLEET_VAR_SMALLSTEP_SCEP_CHALLENGE_WIFI_AUTHENTICATION` and `$FLEET_VAR_SMALLSTEP_SCEP_PROXY_URL_WIFI_AUTHENTICATION`. @@ -497,7 +497,7 @@ When the profile is delivered to your hosts, Fleet will replace the variables. I OU - $FLEET_VAR_SCEP_RENEWAL_ID + $FLEET_VAR_CERTIFICATE_RENEWAL_ID @@ -686,7 +686,7 @@ When the profile is delivered to your hosts, Fleet will replace the variables. I OU - $FLEET_VAR_SCEP_RENEWAL_ID + $FLEET_VAR_CERTIFICATE_RENEWAL_ID @@ -779,7 +779,7 @@ You can add any other options listed under Device/SCEP in the [Microsoft documen chr - CN=$FLEET_VAR_HOST_HARDWARE_SERIAL WIFI,OU=$FLEET_VAR_SCEP_RENEWAL_ID + CN=$FLEET_VAR_HOST_HARDWARE_SERIAL WIFI,OU=$FLEET_VAR_CERTIFICATE_RENEWAL_ID @@ -837,7 +837,7 @@ You can add any other options listed under Device/SCEP in the [Microsoft documen -1. Create a configuration profile (see examples above) with the SCEP payload. In the profile, for `Challenge`, use `$FLEET_VAR_CUSTOM_SCEP_CHALLENGE_{CA_NAME}`. For `URL`, use `$FLEET_VAR_CUSTOM_SCEP_PROXY_URL_{CA_NAME}`, and make sure to add `$FLEET_VAR_SCEP_RENEWAL_ID` to `OU`. +1. Create a configuration profile (see examples above) with the SCEP payload. In the profile, for `Challenge`, use `$FLEET_VAR_CUSTOM_SCEP_CHALLENGE_{CA_NAME}`. For `URL`, use `$FLEET_VAR_CUSTOM_SCEP_PROXY_URL_{CA_NAME}`, and make sure to add `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` to `OU`. 2. Replace the `{CA_NAME}` with the name you created in step 3. For example, if the name of the CA is "WIFI_AUTHENTICATION", the variables will look like this: `$FLEET_VAR_CUSTOM_SCEP_CHALLENGE_WIFI_AUTHENTICATION` and `$FLEET_VAR_CUSTOM_SCEP_PROXY_URL_WIFI_AUTHENTICATION`. @@ -975,9 +975,9 @@ If an end user is on vacation (offline for more than 30 days), their certificate Fleet automatically retries each failed macOS, iOS, iPadOS, and Android certificate up to 3 times per host and each failed Windows certificate once per host (retries [coming soon](https://github.com/fleetdm/fleet/issues/42981)), checking every 30 seconds for certificates to resend. Learn more in the [4.38.0 release article](https://fleetdm.com/releases/fleet-4-38-0#failed-profile-redelivery). Note that manually resending a profile does not reset the automatic retry counter. -> Currently, for NDES, Smallstep, ACME, and SCEP CAs, Fleet requires that the ⁠`$FLEET_VAR_SCEP_RENEWAL_ID` variable is in the certificate's OU (Organizational Unit) for automatic renewal to work for Apple and Windows hosts. For some CAs, including [NDES](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/active-directory-domain-services-maximum-limits?utm_source=chatgpt.com#:~:text=OU%20names%20can%20only%20be%2064%20characters%20long.), the OU has a maximum length of 64 characters so any characters beyond this limit get truncated, causing the renewal to fail. +> Currently, for NDES, Smallstep, ACME, and SCEP CAs, Fleet requires that the ⁠`$FLEET_VAR_CERTIFICATE_RENEWAL_ID` variable is in the certificate's OU (Organizational Unit) for automatic renewal to work for Apple and Windows hosts. For some CAs, including [NDES](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/active-directory-domain-services-maximum-limits?utm_source=chatgpt.com#:~:text=OU%20names%20can%20only%20be%2064%20characters%20long.), the OU has a maximum length of 64 characters so any characters beyond this limit get truncated, causing the renewal to fail. > -> The ⁠`$FLEET_VAR_SCEP_RENEWAL_ID` is a 36 character UUID. Please make sure that any additional variables or content combined with it do not exceed the remaining 28 characters. +> The `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` is a 36 character UUID. Please make sure that any additional variables or content combined with it do not exceed the remaining 28 characters. > > Please confirm your CA supports the OU value in the certificate it issues. > diff --git a/articles/enable-okta-verify-on-macOS-with-configuration-profile.md b/articles/enable-okta-verify-on-macOS-with-configuration-profile.md index 0a9de29afd..982f455194 100644 --- a/articles/enable-okta-verify-on-macOS-with-configuration-profile.md +++ b/articles/enable-okta-verify-on-macOS-with-configuration-profile.md @@ -80,12 +80,12 @@ The next step to ensure Okta detects the device as managed is to issue a SCEP ce %ComputerName% managementAttestation %HardwareUUID% - - - OU - $FLEET_VAR_CERTIFICATE_RENEWAL_ID - - + + + OU + $FLEET_VAR_CERTIFICATE_RENEWAL_ID + + PayloadIdentifier @@ -105,6 +105,10 @@ The next step to ensure Okta detects the device as managed is to issue a SCEP ce > Make sure to use `.mobileconfig` as the file extension +> **Automatic renewal**: the `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` variable in the OU is what enables Fleet to auto-renew this certificate. Include it to opt in; omit it to manage renewal manually (the cert will continue to work, but won't auto-renew before expiry). +> +> **CA-side requirement**: your SCEP CA must preserve the Subject OU in issued certificates for auto-renewal to work. Verify by decoding an issued cert (Keychain Access → Get Info, or `openssl x509 -text`) and confirming the OU contains `fleet-` after deployment. + * Enforce the configuration profile on your hosts. You can follow [this guide on enforcing custom OS settings in Fleet](https://fleetdm.com/guides/custom-os-settings). * You can optionally verify the issued certificate by opening Keychain Access on the device or by running a [live report](https://fleetdm.com/guides/get-current-telemetry-from-your-devices-with-live-queries): diff --git a/articles/enable-okta-verify-on-windows-using-a-scep-configuration-profile.md b/articles/enable-okta-verify-on-windows-using-a-scep-configuration-profile.md index cd1e266a55..565cfce0d0 100644 --- a/articles/enable-okta-verify-on-windows-using-a-scep-configuration-profile.md +++ b/articles/enable-okta-verify-on-windows-using-a-scep-configuration-profile.md @@ -139,11 +139,21 @@ Review Device Management logs: Get-WinEvent -LogName Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Admin -MaxEvents 50 ``` -## Plan and automate renewal +## Automatic renewal -### Monitor expiration +Include `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` in the SubjectName OU of your SCEP profile to opt into auto-renewal. Fleet renews certificates about 30 days before expiration; new profiles deployed without this variable continue to work but must be renewed manually. -Use a Fleet policy to identify devices with certificates expiring within 30 days: +**Example SubjectName containing the marker:** + +``` +CN=$FLEET_VAR_HOST_HARDWARE_SERIAL managementAttestation,OU=$FLEET_VAR_CERTIFICATE_RENEWAL_ID +``` + +**CA-side requirement**: your SCEP CA must preserve the Subject OU in issued certificates. Verify by decoding an issued cert (`openssl x509 -text`) and confirming the OU contains `fleet-` after deployment. + +### Monitor expiration (optional safeguard) + +If you'd like a manual safeguard alongside auto-renewal, use a Fleet policy to flag devices with certificates expiring soon: ```sql SELECT 1 @@ -153,15 +163,11 @@ WHERE AND julianday(not_valid_after) - julianday('now') < 30; ``` -This policy will: -- **Fail**: When a certificate exists and expires within 30 days (needs renewal) +The policy will: +- **Fail**: When a certificate exists and expires within 30 days - **Pass**: When no certificate exists yet, or certificate is valid for more than 30 days -### Renewal workflow - -To renew certificates, you can: - -**Manual redeployment**: Redeploy the same configuration profile to trigger renewal +If you haven't opted into auto-renewal, redeploy the same configuration profile to trigger renewal manually. ## Important notes diff --git a/articles/lock-wipe-hosts.md b/articles/lock-wipe-hosts.md index 51d0419da8..a863fb55da 100644 --- a/articles/lock-wipe-hosts.md +++ b/articles/lock-wipe-hosts.md @@ -61,6 +61,8 @@ Example URL: Wiping a host silently cancels all of its upcoming activities — no canceled activity entries are added to the host's activity history. +Wiping a host silently cancels all of its upcoming activities — no canceled activity entries are added to the host's activity history. + When wiping and re-installing the operating system (OS) on a host, delete the host from Fleet before you re-enroll it. If you re-enroll without deleting, Fleet won't escrow a new disk encryption key. If you're gifting a company-owned macOS host or you want to prevent the host from automatically re-enrolling to Fleet for some other reason, first release the host from Apple Business (AB) and then delete the host in Fleet. diff --git a/articles/okta-conditional-access-integration.md b/articles/okta-conditional-access-integration.md index f42f5e7bfc..7d0700fd1a 100644 --- a/articles/okta-conditional-access-integration.md +++ b/articles/okta-conditional-access-integration.md @@ -77,6 +77,8 @@ Replace: Deploying this profile will deploy a SCEP certificate to your hosts. These certificates are valid for 1 year and 33 days and Fleet will automatically renew them. [Learn more](https://fleetdm.com/guides/connect-end-user-to-wifi-with-certificate#renewal). +> **Upgrading from Fleet 4.85 or earlier?** Your existing Conditional Access deployment continues to work, but auto-renewal activates only on profiles redeployed in 4.86 or later. To opt in, re-download the User scope profile above and re-deploy via custom OS settings. + > If using GitOps, use the challenge in a [secret variable](https://fleetdm.com/guides/secrets-in-scripts-and-configuration-profiles), instead of hardcoding into the profile. ## Step 3: Create IdP in Okta diff --git a/changes/40639-non-proxied-cert-renewal b/changes/40639-non-proxied-cert-renewal new file mode 100644 index 0000000000..a820a992ab --- /dev/null +++ b/changes/40639-non-proxied-cert-renewal @@ -0,0 +1,3 @@ +* Added automatic renewal for SCEP and ACME certificates issued by external certificate authorities (Okta Conditional Access, Okta Verify, Hydrant ACME). Add `$FLEET_VAR_CERTIFICATE_RENEWAL_ID` to the certificate's Subject OU to enable. +* Renamed `$FLEET_VAR_SCEP_RENEWAL_ID` to `$FLEET_VAR_CERTIFICATE_RENEWAL_ID`. The legacy name still works. +* Enabled automatic renewal by default in Fleet's generated Conditional Access profile. Existing customers can opt in by redeploying the User scope profile. diff --git a/changes/42827-macos-mdm-certificate-ingestion b/changes/42827-macos-mdm-certificate-ingestion new file mode 100644 index 0000000000..685b4263b4 --- /dev/null +++ b/changes/42827-macos-mdm-certificate-ingestion @@ -0,0 +1 @@ +* Surface hardware-bound ACME certificates on macOS host vitals by retrieving them via the MDM `CertificateList` command when an ACME-bearing configuration profile is installed or re-installed. diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index 07a13b8721..046c7c5fe1 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -8113,9 +8113,9 @@ This endpoint returns the list of custom MDM commands that have been executed. | Name | Type | In | Description | | ------------------------- | ------ | ----- | ------------------------------------------------------------------------- | | host_identifier | string | query | **Required.** The host's `hostname`, `uuid`, or `hardware_serial`. Returns only commands that target the specified host. Omitting `host_identifier` is deprecated (see the deprecation notice below). Requests w/o it continue to work for backward compatibility but are not recommended; the underlying query is not performant at scale and may time out on large fleets. Support will be removed in Fleet 5. | -| page | integer | query | Page number of the results to fetch. | -| per_page | integer | query | Results per page. Default is `10`. | -| order_key | string | query | What to order results by. Can be any field listed in the `results` array example below. Default is `updated_at`. | +| page | integer | query | Page number of the results to fetch. Maximum is `100`. | +| per_page | integer | query | Results per page. Default is `10`. Maximum is 1,000 records. | +| order_key | string | query | What to order results by. Allowed values: `host_uuid`, `command_uuid`, `status`, `updated_at`, `request_type`, `hostname`. Default is `updated_at`. | | order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include `"asc"` and `"desc"`. Default is `"asc"`. | | request_type | string | query | The request type to filter commands by. | | command_status | string | query | Comma-separated string of one of the following options: 'ran', 'pending', or 'failed'. |