Skip to content

Commit 5f175fb

Browse files
tashianclaude
andcommitted
docs(fleet): split Windows SyncML back into two profiles with SCEP retry
Fleet returns 502 on multi-element configuration profiles (POST /api/latest/fleet/mdm/profiles), even though Fleet's docs and own Okta bundle suggest single-file Replace+Exec ordering is supported. The UI silently swallows the 502, which is why the merged profile never appears in the list. Revert to two separate profiles (smallstep-windows-root-ca.xml and smallstep-windows-scep.xml). Since Fleet does not let you order profiles, add RetryCount=3 and RetryDelay=10 to the SCEP Install nodes so SCEP enrollment retries if the Root CA trust isn't in place on first attempt. Renumber Windows steps to 1-8 (was 1-7), update GitOps directory layout and team-YAML windows_settings to reference both files, and update the cross-reference to the PowerShell registry step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent bd28a40 commit 5f175fb

1 file changed

Lines changed: 58 additions & 30 deletions

File tree

tutorials/connect-fleet-dm-to-smallstep.mdx

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -417,13 +417,29 @@ Fleet's NDES CA type is single-instance — you can have at most one NDES CA at
417417
</div>
418418
</Alert>
419419

420-
## Step 3. Create the Windows SyncML profile (`smallstep-windows.xml`)
420+
## Step 3. Create the Windows Root CA trust profile (`smallstep-windows-root-ca.xml`)
421421

422-
Fleet does not let you order separately uploaded SyncML profiles, so we put everything Windows needs into a single file. Within one profile, Fleet processes top-level commands in document order, so we can guarantee:
422+
To install the Smallstep Root CA in the device's Trusted Root store, create a SyncML profile using the `RootCATrustedCertificates` CSP. Replace `YOUR_ROOT_CA_FINGERPRINT` with the SHA-1 **Root Certificate Fingerprint** from the Smallstep Workspace ONE connector Settings page (hex string, no colons — switch the dropdown next to **Root Certificate Fingerprint** to **sha1**). Paste the Base64 body of the Root CA PEM (everything between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`) into the `<Data>` element.
423423

424-
1. The Smallstep Root CA is installed in the device's Trusted Root store
425-
2. The SCEP CSP nodes are populated
426-
3. The SCEP `Enroll` is triggered last
424+
```xml
425+
<Replace>
426+
<Item>
427+
<Target>
428+
<LocURI>./Device/Vendor/MSFT/RootCATrustedCertificates/Root/YOUR_ROOT_CA_FINGERPRINT/EncodedCertificate</LocURI>
429+
</Target>
430+
<Meta>
431+
<Format xmlns="syncml:metinf">b64</Format>
432+
</Meta>
433+
<Data>
434+
<!-- Paste the Base64-encoded Root CA certificate here -->
435+
</Data>
436+
</Item>
437+
</Replace>
438+
```
439+
440+
## Step 4. Create the Windows SCEP profile (`smallstep-windows-scep.xml`)
441+
442+
Create a second SyncML profile that requests a SCEP certificate. Fleet doesn't let you order the application of separately uploaded profiles, so the SCEP install may run before Root CA trust is established. The `RetryCount` and `RetryDelay` nodes below tell Windows to retry the SCEP install several times — by the time the retries fire, the Root CA Replace from Step 3 will have applied and the chain will validate.
427443

428444
Fleet substitutes these variables per host at deployment time:
429445

@@ -434,34 +450,39 @@ Fleet substitutes these variables per host at deployment time:
434450
| `$FLEET_VAR_SCEP_RENEWAL_ID` | Per-device renewal identifier |
435451
| `$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID` | Per-device certificate node ID in the Windows MDM CSP |
436452

437-
Get the **CA Thumbprint** from the Smallstep Workspace ONE connector Settings page: switch the dropdown next to **Root Certificate Fingerprint** to **sha1** and copy that value. The Windows SCEP CSP expects a SHA-1 fingerprint for `CAThumbprint`.
438-
439-
Create `smallstep-windows.xml` with the following contents. Replace `YOUR_ROOT_CA_FINGERPRINT` (in two places) with the SHA-1 Root Certificate Fingerprint, and paste the Base64 body of the Root CA PEM (everything between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`) into the `<Data>` element of the first `<Replace>`:
453+
Replace `YOUR_ROOT_CA_FINGERPRINT` with the same SHA-1 fingerprint used in Step 3:
440454

441455
```xml
442-
<!-- 1. Install the Smallstep Root CA in the device's Trusted Root store -->
443456
<Replace>
444457
<Item>
445458
<Target>
446-
<LocURI>./Device/Vendor/MSFT/RootCATrustedCertificates/Root/YOUR_ROOT_CA_FINGERPRINT/EncodedCertificate</LocURI>
459+
<LocURI>./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID</LocURI>
447460
</Target>
448461
<Meta>
449-
<Format xmlns="syncml:metinf">b64</Format>
462+
<Format xmlns="syncml:metinf">node</Format>
450463
</Meta>
451-
<Data>
452-
<!-- Paste the Base64-encoded Root CA certificate here (contents between the BEGIN/END lines of the PEM) -->
453-
</Data>
454464
</Item>
455465
</Replace>
456-
<!-- 2. Populate the SCEP CSP nodes -->
457466
<Replace>
458467
<Item>
459468
<Target>
460-
<LocURI>./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID</LocURI>
469+
<LocURI>./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/RetryCount</LocURI>
461470
</Target>
462471
<Meta>
463-
<Format xmlns="syncml:metinf">node</Format>
472+
<Format xmlns="syncml:metinf">int</Format>
473+
</Meta>
474+
<Data>3</Data>
475+
</Item>
476+
</Replace>
477+
<Replace>
478+
<Item>
479+
<Target>
480+
<LocURI>./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/RetryDelay</LocURI>
481+
</Target>
482+
<Meta>
483+
<Format xmlns="syncml:metinf">int</Format>
464484
</Meta>
485+
<Data>10</Data>
465486
</Item>
466487
</Replace>
467488
<Replace>
@@ -552,7 +573,6 @@ Create `smallstep-windows.xml` with the following contents. Replace `YOUR_ROOT_C
552573
<Data>YOUR_ROOT_CA_FINGERPRINT</Data>
553574
</Item>
554575
</Replace>
555-
<!-- 3. Trigger SCEP enrollment -->
556576
<Exec>
557577
<Item>
558578
<Target>
@@ -562,16 +582,22 @@ Create `smallstep-windows.xml` with the following contents. Replace `YOUR_ROOT_C
562582
</Exec>
563583
```
564584

565-
## Step 4. Upload the profile to Fleet
585+
<Alert severity="info">
586+
<div>
587+
Fleet's documentation suggests that a single configuration profile can contain multiple top-level `<Replace>` / `<Exec>` commands ordered by document order, but in our testing the Fleet API returns a 502 on such bundled profiles. Keeping the Root CA and SCEP profiles separate is what works in practice — the `RetryCount` setting above papers over the lack of profile ordering.
588+
</div>
589+
</Alert>
590+
591+
## Step 5. Upload the profiles to Fleet
566592

567593
1. In the Fleet console, go to **Controls → OS settings → Configuration profiles**
568-
2. Click **Add profile**
569-
3. Upload `smallstep-windows.xml`
570-
4. Scope the profile to the teams or labels containing your Windows hosts
594+
2. Click **Add profile** and upload `smallstep-windows-root-ca.xml`
595+
3. Click **Add profile** again and upload `smallstep-windows-scep.xml`
596+
4. Scope both profiles to the teams or labels containing your Windows hosts
571597

572-
The profile will be deployed to devices at their next MDM check-in. Fleet substitutes the `$FLEET_VAR_*` values per host.
598+
The profiles will be deployed to devices at their next MDM check-in. Fleet substitutes the `$FLEET_VAR_*` values per host.
573599

574-
## Step 5. Configure the Smallstep agent via a PowerShell script
600+
## Step 6. Configure the Smallstep agent via a PowerShell script
575601

576602
The Windows Smallstep agent reads its configuration from `HKLM:\Software\Policies\Smallstep`. Fleet does not have native registry-management, so we set those values with a PowerShell script run by Fleet's [Scripts](https://fleetdm.com/guides/scripts) feature.
577603

@@ -609,7 +635,7 @@ Upload the script to Fleet and run it against your Windows hosts:
609635

610636
For self-healing enforcement, you can pair this with a [policy automation](https://fleetdm.com/guides/policy-automation-run-script) that checks whether the registry values exist and re-runs the script if they're missing — Fleet documents this pattern in [Prevent tampering of Fleet Orbit](https://fleetdm.com/guides/prevent-tampering-of-fleet-agent).
611637

612-
## Step 6. Deploy the Smallstep agent
638+
## Step 7. Deploy the Smallstep agent
613639

614640
Add the Smallstep agent MSI as Fleet software so it installs on enrollment:
615641

@@ -620,9 +646,9 @@ Add the Smallstep agent MSI as Fleet software so it installs on enrollment:
620646
2. In the Fleet console, go to **Software**, choose **Add software → Custom package**, and upload the MSI
621647
3. Scope the install to your Windows hosts
622648

623-
The agent reads the registry values written in Step 5 on startup, finds the bootstrap certificate from Step 3, and completes TPM-attested registration with your Smallstep team.
649+
The agent reads the registry values written in Step 6 on startup, finds the bootstrap certificate from Step 4, and completes TPM-attested registration with your Smallstep team.
624650

625-
## Step 7. Confirmation (Windows)
651+
## Step 8. Confirmation (Windows)
626652

627653
On a Fleet-enrolled Windows test host:
628654

@@ -661,7 +687,8 @@ fleet-gitops/
661687
│ └── team.yml
662688
└── lib/
663689
├── smallstep-agent.mobileconfig
664-
├── smallstep-windows.xml
690+
├── smallstep-windows-root-ca.xml
691+
├── smallstep-windows-scep.xml
665692
└── smallstep-agent-setup.sh
666693
```
667694

@@ -712,7 +739,8 @@ controls:
712739
- path: ../lib/smallstep-agent.mobileconfig
713740
windows_settings:
714741
custom_settings:
715-
- path: ../lib/smallstep-windows.xml
742+
- path: ../lib/smallstep-windows-root-ca.xml
743+
- path: ../lib/smallstep-windows-scep.xml
716744
```
717745

718746
## Add the Smallstep agent software
@@ -759,7 +787,7 @@ If your Linux fleet includes multiple architectures, add entries for each varian
759787

760788
Adapt the label names to match your Fleet label configuration. Fleet includes built-in labels for common Linux distributions. For architecture-specific targeting, you can create [custom labels](https://fleetdm.com/guides/managing-labels-in-fleet) using osquery queries (for example, `SELECT 1 FROM system_info WHERE cpu_type = 'x86_64'`).
761789

762-
The PowerShell registry script from the Windows [Step 5](#step-5-configure-the-smallstep-agent-via-a-powershell-script) is run from the Fleet UI rather than GitOps. If you want it under version control, manage it through Fleet's [scripts API](https://fleetdm.com/docs/rest-api/rest-api#scripts).
790+
The PowerShell registry script from the Windows [Step 6](#step-6-configure-the-smallstep-agent-via-a-powershell-script) is run from the Fleet UI rather than GitOps. If you want it under version control, manage it through Fleet's [scripts API](https://fleetdm.com/docs/rest-api/rest-api#scripts).
763791

764792
## Apply the configuration
765793

0 commit comments

Comments
 (0)