Repository navigation
Deploy certificates from NDES CA on Windows #33421
Description
Goal
| User story |
|---|
| As an IT admin, |
| I want to deploy certificates from my NDES certificate authority (CA) on my Windows hosts (device and user scope) |
| so that I can grant end users access to Wi-Fi and VPN. |
Changes
Product
- UI changes: No changes. The existing NDES CA configuration UI (Settings > Integrations > Certificates > Microsoft NDES) already works for both macOS and Windows. Windows profiles are uploaded via Controls > OS settings > Custom settings, which already supports SyncML profiles with Fleet variables.
- CLI (fleetctl) usage changes: No changes.
fleetctl applyalready supports uploading Windows SyncML profiles with Fleet variables. - YAML changes: No changes. The existing NDES SCEP proxy YAML configuration (
certificate_authorities.ndes_scep_proxy) applies to both macOS and Windows. - REST API changes: No changes. The existing profile upload endpoint (
POST /api/v1/fleet/mdm/profiles) already accepts Windows SyncML profiles. The only change is that NDES Fleet variables ($FLEET_VAR_NDES_SCEP_CHALLENGE,$FLEET_VAR_NDES_SCEP_PROXY_URL) are now accepted in Windows profiles, where they were previously rejected. - Fleet's agent (fleetd) changes: No changes. Certificate enrollment is handled by the Windows MDM client via the ClientCertificateInstall CSP, not by fleetd.
- GitOps mode UI changes: No changes.
- GitOps generation changes: No changes.
- Activity changes: No changes. Profile upload and deployment activities already cover Windows profiles.
- Permissions changes: No changes. Same permissions as existing Windows profile management (admin, maintainer, GitOps).
- Changes to paid features or tiers: Fleet Premium. NDES SCEP is already a premium-only feature. No changes to the pricing page.
- My device and fleetdm.com/better changes: No changes.
- Usage statistics: No changes.
- Other reference documentation changes: Update the certificate deployment guide to change "macOS and Windows (coming soon)" to "macOS and Windows" for NDES, and add a Windows SyncML example profile under the Microsoft NDES section.
- First draft of test plan added
- Once shipped, requester has been notified
- Once shipped, dogfooding issue has been filed
Engineering
- Test plan is finalized
- Contributor API changes: No changes.
- Feature guide changes: Update
articles/connect-end-user-to-wifi-with-certificate.md— add a Windows subsection under Microsoft NDES with a SyncML example profile using$FLEET_VAR_NDES_SCEP_CHALLENGE,$FLEET_VAR_NDES_SCEP_PROXY_URL, and$FLEET_VAR_SCEP_RENEWAL_IDin the ClientCertificateInstall CSP format (both Device and User scope examples). - Database schema migrations: None required. Existing tables (
mdm_windows_configuration_profiles,host_mdm_windows_profiles,mdm_managed_certificates) already support this. - This is a premium only feature: Yes
Implementation summary
This extends the existing Windows Custom SCEP flow to also support NDES. All NDES infrastructure (challenge retrieval, SCEP proxy, certificate renewal) and all Windows SCEP infrastructure (SyncML validation, ClientCertificateInstall CSP, variable replacement) already exist. The work connects these two systems:
-
Profile validation (
server/service/windows_mdm_profiles.go): Allow$FLEET_VAR_NDES_SCEP_CHALLENGEand$FLEET_VAR_NDES_SCEP_PROXY_URLin Windows profiles. Add an NDES-specific validation callback to ensure the variables appear in the correct SyncML locations (Challenge inInstall/Challenge, proxy URL inInstall/ServerURL, renewal ID inSubjectName). -
Variable replacement at deployment time (
server/mdm/microsoft/profile_variables.go): Add NDES variable replacement cases. When a Windows profile with NDES variables is deployed to a host, Fleet fetches a one-time challenge from the NDES admin URL (57-minute TTL) and builds a SCEP proxy URL immediately before sending the SyncML to the device. A managed certificate record is created for renewal tracking. -
Error handling: Surface descriptive errors when NDES challenge retrieval fails (invalid credentials, password cache full, insufficient permissions) as profile delivery failures visible in Host details > OS settings.
-
Documentation: Add a Windows NDES SyncML example profile and update the certificate deployment guide.
The SCEP proxy (/mdm/scep/proxy/{identifier}) is already platform-agnostic and handles NDES proxying. Certificate renewal via mdm_managed_certificates already works for Windows. No database migrations needed.
ℹ️ Please read this issue carefully and understand it. Pay special attention to UI wireframes, especially "dev notes".
QA
Risk assessment
- Risk level: Low
- All infrastructure exists on both sides (NDES and Windows SCEP). This extends an existing pattern (Custom SCEP on Windows) to a new CA type (NDES). The SCEP proxy is platform-agnostic and already handles NDES. The main area to verify is that the Windows SCEP CSP correctly enrolls via Fleet's SCEP proxy URL.
Test plan
Prerequisites: Fleet Premium license, Windows host enrolled via MDM, NDES server configured and accessible.
- Deploy the root CA certificate (from the guide).
Setup
- Configure NDES CA in Fleet: go to Settings > Integrations > Certificates, add Microsoft NDES with SCEP URL, Admin URL, username, and password. Verify CA appears in the list.
Device scope
- Upload a Windows SyncML NDES SCEP profile using
./Device/...LocURIs containing$FLEET_VAR_NDES_SCEP_CHALLENGE,$FLEET_VAR_NDES_SCEP_PROXY_URL,$FLEET_VAR_SCEP_RENEWAL_ID, and$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID. Verify it is accepted. - Assign the profile to a team with a Windows host. Wait for profile deployment.
- Verify the profile status transitions to "Verifying" then "Verified" in Host details > OS settings.
- On the Windows host, verify the certificate appears in
Cert:\LocalMachine\Myusing PowerShell:Get-ChildItem -Path Cert:\LocalMachine\My.
User scope
- Upload a Windows SyncML NDES SCEP profile using
./User/...LocURIs. Verify it is accepted. - Assign and deploy to a Windows host. Verify profile status reaches "Verified".
- On the Windows host, verify the certificate appears in
Cert:\CurrentUser\My.
Validation errors
- Upload a Windows profile with
$FLEET_VAR_NDES_SCEP_CHALLENGEbut without$FLEET_VAR_NDES_SCEP_PROXY_URL. Verify it is rejected with an appropriate error message. - Upload a Windows profile with
$FLEET_VAR_NDES_SCEP_PROXY_URLbut without$FLEET_VAR_NDES_SCEP_CHALLENGE. Verify it is rejected. - Upload a Windows profile with NDES variables but no NDES CA configured. Verify it is rejected.
- Upload a Windows profile with both NDES and Custom SCEP variables. Verify it is rejected.
- Upload a Windows profile with NDES variables but missing
$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID. Verify it is rejected. - Verify a non-premium instance rejects profiles with NDES variables.
Error scenarios
- Configure NDES CA with incorrect credentials. Upload and deploy a valid NDES profile. Verify the profile shows "Failed" status with a message about invalid credentials.
- Fix the NDES credentials. Resend the profile. Verify it succeeds.
Renewal
- Deploy a Windows NDES certificate. After it reaches "Verified" status, update the
not_valid_aftercolumn inmdm_managed_certificatesto a date within 30 days. Verify Fleet re-deploys the profile with a new challenge on the next renewal cron cycle.
GitOps
- Apply a Windows NDES SCEP profile via
fleetctl gitopswith GitOps YAML. Verify it is accepted and deployed.
Testing notes
- A Windows NDES test environment is required.
- The NDES server in Proxmox keeps having the wrong time (~9 hours in the future). This causes cert delivery to fail. I used a Powershell command to set it.
- The SCEP proxy URL format for NDES is:
{MDMUrl}/mdm/scep/proxy/{hostUUID},{profileUUID},NDES
Confirmation
- Engineer: Added comment to user story confirming successful completion of test plan.
- QA: Added comment to user story confirming successful completion of test plan.
Demo video
https://www.youtube.com/watch?v=-mpW8o4vqu0
Docs
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsClosed
- StatusShow more project fieldsDone
Activity
21 remaining items
getvictor commentedon Mar 16, 2026
Latest guide PR: #41730
Brajim20 commentedon Mar 28, 2026
Tested on Fleet v4.83.0-rc, Windows 11 (ARM), NDES CA configured via Okta
Cert:\LocalMachine\My— blocked (wrong CA thumbprint)Cert:\CurrentUser\My$FLEET_VAR_NDES_SCEP_PROXY_URLcorrectly rejected$FLEET_VAR_NDES_SCEP_CHALLENGEcorrectly rejected$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_IDcorrectly rejectedfleet-release commentedon Apr 7, 2026
NDES deployment shines,
Windows hosts gain swift access,
Wi-Fi and VPN lines.
SyncML's embrace,
In clouds above, certificates trace,
Managed with Fleet's grace.
No changes required,
In glass city admired,
IT admin's load, lightened, admired.