Microsoft 365, Intune, identity and endpoint engineeringAdelaide, Australia
Implementation guide

Set up NDES and SCEP for Intune with Azure Blob CRL publishing

A production-minded deployment guide for AD CS, NDES, the Intune Certificate Connector, SCEP profiles and highly available CRL distribution through Azure Blob Storage.

This design uses an on-premises or Azure-hosted Microsoft Enterprise CA, dedicated NDES servers, the Microsoft Intune Certificate Connector and Intune SCEP profiles. Azure Blob Storage provides an unauthenticated, highly available endpoint for certificate revocation lists so devices and relying services can perform revocation checks from managed networks and the internet.

Security exception requiredCRLs must be retrievable without user authentication. Azure Storage disables anonymous blob access by default and Microsoft recommends keeping it disabled generally. Use a dedicated storage account containing only public PKI artefacts, enable anonymous blob read only for the CRL container, and never store private keys, secrets or internal documents there.

Reference architecture

ComponentPurposeDesign note
Enterprise issuing CAIssues device or user certificatesDo not install the Intune connector or NDES on the issuing CA.
NDES serverReceives SCEP requests through IISUse at least two servers for production resilience and patching.
Intune Certificate ConnectorInstalls the Intune SCEP policy module and validates Intune challenge dataSelect SCEP and, where required, certificate revocation during connector configuration.
Reverse proxy or application delivery servicePublishes the NDES URL to devicesSCEP preauthentication must be passthrough; the Intune policy module validates requests.
Azure Blob StorageHosts base and delta CRLs over a public HTTPS URLUse a dedicated container with blob-level anonymous read and no container listing.
Intune profilesDeploy CA trust, SCEP settings and Wi-Fi/VPN configurationAssign trusted-root and SCEP profiles to the same user or device population.

Prerequisites and decisions

  • Enterprise CA is healthy, backed up and able to issue the intended template.
  • NDES service account and connector service account are defined with least privilege.
  • NDES servers are not installed on the issuing CA.
  • Subject, SAN and EKU values are agreed with the relying service such as Cisco ISE, NPS or VPN.
  • KDC strong certificate mapping requirements have been assessed for hybrid-joined Windows authentication scenarios.
  • External DNS, TLS certificate and reverse-proxy routing are available for the SCEP endpoint.
  • CRL validity, overlap, delta CRL and publication schedules are documented.
  • A dedicated Azure subscription/resource group and storage account are approved for public PKI artefacts.

Create Azure Blob storage for CRLs

  1. Create a general-purpose v2 storage account in the approved region. Require secure transfer and TLS 1.2 or later. Use a dedicated account rather than enabling anonymous access on an account that stores other data.
  2. At the storage account level, allow blob anonymous access. This only permits a container to be made public; it does not publish data by itself.
  3. Create a container named pki and set its access level to Blob, not Container. This permits anonymous reads of known blob URLs while preventing anonymous container listing.
  4. Grant the publishing identity Storage Blob Data Contributor scoped as narrowly as practical. Do not use the storage account key in a scheduled script.
  5. Upload a test file and confirm that its exact HTTPS URL is available without a sign-in or SAS token.
az storage account update \
  --name <storage-account> \
  --resource-group <resource-group> \
  --allow-blob-public-access true

az storage container create \
  --name pki \
  --account-name <storage-account> \
  --auth-mode login

az storage container set-permission \
  --name pki \
  --account-name <storage-account> \
  --public-access blob \
  --auth-mode login

The resulting URL format is:

https://<storage-account>.blob.core.windows.net/pki/<crl-file-name>.crl

Configure the CA’s CDP and CRL schedule

  1. Open the Certification Authority console, open the CA properties and select the Extensions tab.
  2. Keep a local file-system CRL publication path under %windir%\System32\CertSrv\CertEnroll. AD CS writes CRLs locally; the upload process then copies them to Azure.
  3. Add the Azure Blob HTTPS URL as a CRL Distribution Point using the same generated filename pattern, for example <CaName><CRLNameSuffix><DeltaCRLAllowed>.crl.
  4. For the HTTPS URL, select the option to include it in the CDP extension of issued certificates. Do not select Publish CRLs to this location for an HTTP or HTTPS URL because AD CS cannot write directly to it.
  5. Set base CRL, delta CRL and overlap periods that leave enough time to recover a failed publication before the current CRL expires.
  6. Restart Certificate Services during an approved change window and publish a new CRL.
certutil -getreg CA\CRLPublicationURLs
certutil -getreg CA\CRLPeriod
certutil -getreg CA\CRLDeltaPeriod
certutil -crl

Get-ChildItem "$env:SystemRoot\System32\CertSrv\CertEnroll" -Filter *.crl
ImportantChanging a CDP URL affects newly issued certificates. Existing certificates retain the CDP embedded when they were issued. Maintain the previous CRL endpoint until all dependent certificates have expired or been replaced.

Automate CRL publication to Azure

A regulated environment should avoid long-lived SAS tokens or storage keys on the CA. A stronger pattern is to copy the generated CRL to a hardened automation host and upload it with an Entra service principal that uses certificate authentication. Where the CA itself performs the upload, limit the credential, modules and outbound access to the minimum required.

param(
  [Parameter(Mandatory)] [string]$TenantId,
  [Parameter(Mandatory)] [string]$ApplicationId,
  [Parameter(Mandatory)] [string]$CertificateThumbprint,
  [Parameter(Mandatory)] [string]$StorageAccountName,
  [string]$ContainerName = "pki",
  [string]$SourcePath = "$env:SystemRoot\System32\CertSrv\CertEnroll"
)

$ErrorActionPreference = 'Stop'
Import-Module Az.Accounts
Import-Module Az.Storage

Connect-AzAccount -ServicePrincipal `
  -Tenant $TenantId `
  -ApplicationId $ApplicationId `
  -CertificateThumbprint $CertificateThumbprint | Out-Null

$context = New-AzStorageContext `
  -StorageAccountName $StorageAccountName `
  -UseConnectedAccount

$files = Get-ChildItem -Path $SourcePath -File |
  Where-Object { $_.Extension -in '.crl', '.crt' }

foreach ($file in $files) {
  Set-AzStorageBlobContent `
    -Context $context `
    -Container $ContainerName `
    -File $file.FullName `
    -Blob $file.Name `
    -Force | Out-Null
}

Write-Output "Published $($files.Count) PKI files to Azure Blob Storage."

Run the upload after each CRL publication. Monitor the scheduled task, last modified time, HTTP availability and the CRL’s Next Update field. Alert well before expiry.

Install and configure NDES

  1. Build a supported Windows Server and patch it before installing roles.
  2. Add Active Directory Certificate Services with the Network Device Enrollment Service role, IIS, required ASP.NET/.NET components and IIS management compatibility components.
  3. Configure NDES with a dedicated domain service account and the approved issuing CA.
  4. Create certificate templates for the intended user or device use case. Grant the NDES service account Read and Enrol permissions, and avoid granting broader CA administration.
  5. Configure the NDES template registry values to the template names that match signature, encryption or general-purpose requests.
  6. Bind a trusted TLS certificate to the IIS site. Confirm the external SCEP URL resolves to the publishing tier and reaches /certsrv/mscep/mscep.dll.
  7. Harden the server: restrict interactive logon, apply endpoint protection, limit management access, review service-account rights and monitor IIS and NDES events.

Install the Intune Certificate Connector

  1. Download the current Certificate Connector for Microsoft Intune from the Intune admin centre.
  2. Run the installer as a local administrator on each NDES server.
  3. Open the connector configuration wizard and select SCEP. Select certificate revocation only when your design requires Intune-triggered revocation and the service account permissions are approved.
  4. Choose the connector service-account model and authenticate the connector to the correct Microsoft Entra tenant.
  5. Rename the connector in Intune so operations can identify the hosting server and region.
  6. Confirm the connector shows active and review the Microsoft Intune Connector event logs for successful registration.
Expected endpoint testAfter the Intune policy module is installed, browsing directly to the SCEP URL commonly returns HTTP 403 Forbidden. This indicates that direct requests are blocked; valid device requests include the Intune challenge data that the policy module validates.

Create and assign Intune profiles

  1. Create a Trusted certificate profile for the root and, where required, issuing CA certificate.
  2. Create a separate SCEP certificate profile with the approved subject, SAN, EKU, key size, hash algorithm and renewal threshold.
  3. Enter the published NDES URL. Where you have two NDES endpoints, use the supported load-balanced name or multiple URLs according to platform and design.
  4. Assign the trusted-root and SCEP profiles to the same user or device group. Avoid mixing user assignment for one profile with device assignment for the other.
  5. Create Wi-Fi, VPN or application profiles that select the issued certificate and trusted roots.
  6. Pilot with a small group and a separate certificate template before changing production network policy.

Validate end to end

# NDES endpoint should be reachable and normally return 403 after policy-module protection
Invoke-WebRequest "https://scep.contoso.com/certsrv/mscep/mscep.dll" -UseBasicParsing

# Validate public CRL availability
Invoke-WebRequest "https://<storage-account>.blob.core.windows.net/pki/<ca-name>.crl" -Method Head

# Inspect local certificates and revocation URLs
certutil -store My
certutil -url exported-certificate.cer
certutil -verify -urlfetch exported-certificate.cer

Validate each link in the chain:

  • Intune profile reached the correct user or device.
  • The device trusted the CA before processing the SCEP request.
  • The external SCEP URL reached the intended NDES server.
  • The Intune policy module accepted the challenge and CSR.
  • The CA issued from the intended template.
  • The connector reported the result to Intune.
  • The relying service accepted the subject/SAN and could retrieve the CRL.

Operations, resilience and monitoring

  • Deploy at least two NDES/connector servers and test loss of one server.
  • Monitor connector heartbeat, NDES/IIS events, CA issuance failures and reverse-proxy health.
  • Alert on CRL upload failure, blob HTTP failure and approaching Next Update.
  • Keep CRL blobs in a hot online tier; do not apply a lifecycle rule that moves them to archive.
  • Back up the CA according to the PKI recovery plan. NDES servers should be reproducible from documented configuration.
  • Review public blob access through policy exceptions and ensure the account contains only intended public PKI files.
  • Test revocation, renewal and certificate replacement—not only first-time issuance.

Troubleshooting sequence

StageEvidenceCommon issue
Profile deliveryIntune configuration reporting and device MDM logsTrusted-root and SCEP profiles assigned to different principals.
Device to NDESDNS, proxy logs, IIS logs, HTTP responseURL, TLS chain, firewall or reverse-proxy preauthentication.
Policy moduleNDES and Intune connector event logsChallenge mismatch, connector registration or template configuration.
CA issuanceCA pending/failed requests and template permissionsNDES account lacks Enrol or template purpose does not match.
ReportingMicrosoft Intune Connector event logsConnector outbound connectivity or service-account issue.
AuthenticationRADIUS/VPN/app logs and certificate chain testIncorrect SAN mapping, EKU, trust or unavailable CRL.
Do not place secrets in the public containerThe CRL and CA public certificates are intentionally public. Private keys, PFX files, service-principal certificates, scripts containing credentials and CA backups must remain in protected storage.

Microsoft references

  1. Configure infrastructure to support SCEP with Intune
  2. Certificate Connector prerequisites
  3. Install the Certificate Connector for Microsoft Intune
  4. Create and assign SCEP certificate profiles
  5. Troubleshoot SCEP certificate profiles
  6. Configure anonymous read access for Azure blobs
  7. Upload files to Azure Blob Storage with AzCopy
  8. Certutil command reference

Review note: Certification objectives, Microsoft cloud features and portal labels change. Check the official Microsoft page for the date of your exam or production deployment.