HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Security Certificate-Based AuthenticationCBACRLEntra IDPowerShellMicrosoft Graph

A Revoked Certificate That Still Signs In: The Entra CBA Revocation Gap

IA
Imran Awan
31 July 2026

Certificate-based authentication is the phishing-resistant method most organisations reach for when they want smart cards or PIV credentials to sign in to Microsoft Entra ID directly, with no password and no federation server in the path. It is genuinely strong — right up until the day you need to un-trust a certificate. Revocation is the entire security promise of a PKI: when a device is lost or someone leaves, you revoke their certificate and it stops working. This post is about the one configuration gap that quietly breaks that promise, why the portal gives you no warning at all, and a read-only PowerShell audit that finds it before an auditor — or an attacker — does.

The problem: you revoked the certificate, and it still authenticates

Here is the scenario, and it is uncomfortably common in organisations that adopted CBA early. You stood up certificate-based authentication properly. You uploaded your issuing CA to the Entra trust store, you configured the authentication methods policy, you issued smart-card certificates to your privileged users, and phishing-resistant sign-in worked on the first try. Everyone moved on.

Months later, a contractor with a privileged smart-card certificate leaves under less-than-ideal circumstances. Your PKI team does exactly the right thing: they revoke the contractor's certificate on the issuing CA, the CA publishes an updated certificate revocation list (CRL), and the revoked serial number is now sitting in that CRL for the whole world to see. Job done, as far as anyone can tell.

Except the contractor's certificate still signs in to Entra ID. Not for an hour while a cache clears — indefinitely, right up until the certificate's own expiry date, which could be a year away. Conditional Access still waves it through as phishing-resistant MFA. The sign-in logs show a clean, successful certificate authentication. Nothing anywhere is red.

The uncomfortable part: this is not a bug and it is not an attack. It is Entra behaving exactly as documented. Microsoft's own guidance is explicit: "If an Authentication Policy Administrator skips the configuration of the CRL, Microsoft Entra ID doesn't perform any CRL checks during the certificate-based authentication of the user." No CRL distribution point on the trusted CA means no revocation checking — and a revoked certificate that is never checked is a valid certificate.

The reason nobody catches this is that the portal shows you a healthy, working configuration. CBA is enabled. The CA is present in the trust store. Users are signing in. The single missing field — the CRL distribution point URL on that CA — is not surfaced anywhere as a warning, because an empty CRL URL is a legitimate (if dangerous) configuration that Microsoft deliberately allows.

Entra admin center — Certificate-based authentication, trust store
Contoso Issuing CA 1
Root: No · CRL URL: (not configured)
No revocation
Contoso Root CA
Root: Yes · CRL URL: http://pki.contoso.com/root.crl
CRL set
Require CRL validation
Fail authentication when issuing CA has no CRL
Off

That middle line is the whole story. The issuing CA that actually signs your user certificates has no CRL URL, "Require CRL validation" is switched off, and Entra is therefore accepting every certificate that CA has ever issued — revoked or not — without ever looking at a revocation list. To a casual glance the blade looks fine. You have to know to look at that one field on that one CA.

Why it happens: the trust store, the CRL, and one optional field

Three terms first, because the rest of this leans on them. A certificate authority (CA) in the Entra CBA trust store is the issuer Entra will trust to have signed a user's certificate. A CRL distribution point (CDP) is the internet-facing URL where that CA publishes its certificate revocation list. And the certificate revocation list (CRL) itself is the signed, periodically-republished list of serial numbers the CA has revoked before their natural expiry.

When a user presents a certificate, Entra builds the chain up to a trusted CA in your store, and — if that CA has a CRL URL configured — downloads and caches the CRL to check whether the presented certificate's serial number is on it. If it is, authentication is rejected with AADSTS500171 ("Certificate has been revoked"). If the CA has no CRL URL, that entire step is skipped. There is no revocation list to consult, so there is nothing to reject against.

How Entra decides whether to check revocation
Certificate presented Issuing CA has a CRL URL? YES Download CRL, reject if revoked NO Revocation NOT checked revoked cert still authenticates

Microsoft deliberately makes the CRL URL optional so you can bring a CA online quickly, or troubleshoot, without a working CRL. The documentation is blunt about the trade-off: "You can upload a CA without a CRL endpoint, and certificate-based authentication doesn't fail if an issuing CA doesn't specify a CRL." Helpful during setup; a silent hole in production.

There are a few more mechanics worth knowing, because they explain why this fails so quietly and why the fix has to happen in the right place:

Two trust stores, same field. Older tenants configured CAs under organization/certificateBasedAuthConfiguration (the cmdlet Get-MgOrganizationCertificateBasedAuthConfiguration). Microsoft now recommends the newer PKI-based store under directory/publicKeyInfrastructure/certificateBasedAuthConfigurations, which scales to 250 CAs and adds issuer hints. Both expose a certificateRevocationListUrl per CA, and the "no CRL means no checking" behaviour is identical on both. The audit script reads whichever one (or both) your tenant uses.

There is a second, quieter risk in the same policy: the authentication binding. CBA can treat a presented certificate as either single-factor or multi-factor, controlled by x509CertificateAuthenticationDefaultMode in the authentication methods policy (the values are x509CertificateSingleFactor and x509CertificateMultiFactor). If the default mode is multi-factor and there are no granular rules narrowing that down, every certificate from every trusted CA satisfies MFA on its own — including a soft certificate on an unmanaged device, not just a hardware-backed smart card. That is not necessarily wrong, but it is a decision you want to have made deliberately, not inherited by default. The audit reports it so you can eyeball it.

How to verify: check one CA's CRL field before you trust any script

Before running anything tenant-wide, confirm the mechanism on a single CA so you know what "broken" actually looks like in your environment. You can do this entirely read-only with one Graph call. The example below pulls the legacy trust store and shows the raw certificate authorities; look specifically at certificateRevocationListUrl on the CA that issues your user certificates.

PowerShell 7 — manual single-check (read-only)
# Least-privilege read scope for the legacy trust store
Connect-MgGraph -Scopes "Organization.Read.All"

$org = Get-MgOrganization
Get-MgOrganizationCertificateBasedAuthConfiguration -OrganizationId $org.Id |
    Select-Object -ExpandProperty CertificateAuthorities |
    Format-List Issuer, IsRootAuthority, CertificateRevocationListUrl, IssuerSki

Issuer                       : CN=Contoso Issuing CA 1
IsRootAuthority              : False
CertificateRevocationListUrl : 
IssuerSki                    : 1A2B3C4D5E6F70819200A1B2C3D4E5F600112233

That empty CertificateRevocationListUrl on a non-root, certificate-issuing CA is the finding. Compare it against the sample in Microsoft's own documentation for the newer PKI store, which literally shows a CA object with "certificateRevocationListUrl": null — proof that this is a real, shippable state and not a hypothetical. If your issuing CA looks like the line above, revocation is not being enforced for anything it signed.

Gotcha: do not be reassured by a CRL URL on the root CA. Entra checks the CRL of each CA in the chain, but revocation of an end-user certificate is published by the CA that issued it — almost always an intermediate issuing CA, not the root. A perfectly configured root CRL does nothing for you if the issuing CA below it has an empty certificateRevocationListUrl. Check the issuing CA specifically.

To view the same data in the portal instead: Entra admin center › Protection › Authentication methods › Certificate-based authentication, then open the Configure tab and inspect each certificate authority's CRL settings and the Require CRL validation toggle.

The fix: Get-CbaTrustStoreReport.ps1

Checking one CA by hand is fine for confirming the mechanism. It does not scale to a tenant with multiple issuing CAs, two trust stores, and a policy you last touched eighteen months ago. The companion script reads all of it in one pass and tells you exactly which CAs have no revocation checking, whether "Require CRL validation" is on to catch them, and what the default authentication binding is.

Download the script — GitHub

Download Get-CbaTrustStoreReport.ps1 from the Imran76Awan/Daily-Tasks repository on GitHub — no sign-in required. It is read-only and cannot change anything in your tenant — but always validate any script in your own environment before you rely on it.

Get-CbaTrustStoreReport.ps1 View full repo →

The script connects with three least-privilege, read-only scopes and never asks for anything higher:

Surface readLeast-privilege scopeWhat it tells you
Legacy trust store organization/certificateBasedAuthConfigurationOrganization.Read.AllEach CA's CRL URL, delta CRL URL, root flag, issuer SKI
PKI trust store directory/publicKeyInfrastructurePublicKeyInfrastructure.Read.AllSame fields for CAs in the newer scalable store
CBA policy authenticationMethodsPolicy (X509Certificate)Policy.Read.AuthenticationMethodDefault single/multi-factor mode, rules, Require CRL validation, exempted CAs
Report-only, by design. This script never creates, modifies, deletes, enables, disables, resets, or remediates anything. Every Graph call is a GET, every scope ends in .Read, and there is no code path that writes. It reads your CBA configuration and prints findings — nothing more. Fixing a finding (adding a CRL URL or turning on Require CRL validation) is a deliberate change you make yourself, in a change window, after you have understood it.

It supports app-only certificate authentication for scheduled or unattended runs (-TenantId -ClientId -CertificateThumbprint) and an interactive -UseDeviceCode fallback for ad-hoc checks. It fails loud: if any Graph query errors out — a permission problem, throttling, anything — it sets an error flag, prints the failure, and exits 1 rather than printing a reassuring "0 findings" on data it never actually retrieved. Here is a first run against a tenant with the misconfiguration from the top of this post:

PowerShell 7 — Get-CbaTrustStoreReport.ps1 (initial run)
Connecting to Microsoft Graph (read-only scopes)...
Connected. Tenant: ████████-████-████-████-████████████
  Legacy trust store CAs found : 2
  PKI trust store CAs found    : 0

======================================================================
  ENTRA CBA TRUST STORE REPORT - 31 Jul 2026 09:14
======================================================================
  Total trusted CAs         : 2
  CBA policy state          : enabled
  Default auth mode          : x509CertificateMultiFactor
  Strong-auth rules defined  : 0
  Require CRL validation     : disabled
  CAs exempted from CRL check: 0

======================================================================
  CERTIFICATE AUTHORITIES
======================================================================

  Surface        : Legacy
  Root authority : True
  Issuer         : CN=Contoso Root CA
  Issuer SKI     : 9F8E7D6C5B4A39281706F5E4D3C2B1A099887766
  CRL URL        : http://pki.contoso.com/root.crl
  Delta CRL URL  : <none>
  STATUS         : OK

  Surface        : Legacy
  Root authority : False
  Issuer         : CN=Contoso Issuing CA 1
  Issuer SKI     : 1A2B3C4D5E6F70819200A1B2C3D4E5F600112233
  CRL URL        : <none>
  Delta CRL URL  : <none>
  STATUS         : FINDING: NO CRL - revocation NOT checked

======================================================================
  SUMMARY
======================================================================
  CAs with no revocation checking (findings): 1
  ADVISORY: "Require CRL validation" is NOT enabled - a CA with no CRL will silently skip revocation.
  ADVISORY: default mode is multi-factor with no granular rules - every trusted certificate satisfies MFA. Confirm this is intended.

RESULT: 1 finding(s) detected.

The classification logic is deliberately conservative. A CA is only counted as a hard finding when it has no CRL URL and "Require CRL validation" is not enabled and the CA is not on the exemption list — because in that specific combination, and only that combination, a revoked certificate genuinely sails through. If you have turned on Require CRL validation, a CA with no CRL is reported as "blocked by Require-CRL" instead of a finding, because Entra will now fail those certificates closed rather than open. The advisories about the authentication binding are informational and do not, on their own, change the exit code.

Add -TestCrlReachability and the script will also perform a read-only HTTP GET against each configured CRL URL, so you catch the other failure mode: a CRL URL that is set but returns a 403 or times out, which surfaces at sign-in as AADSTS500173 ("Unable to download a Certificate Revocation List"). A configured-but-unreachable CRL is just as broken as a missing one, only louder — it fails users closed instead of open.

Proof it worked: re-run after configuring the CRL

The remediation here is a PKI and policy change, not a script change, and it happens in two places. First, the PKI team ensures the issuing CA actually publishes its CRL to an internet-facing HTTP endpoint, and that URL is set as the CA's certificateRevocationListUrl in the Entra trust store. Second — and this is the belt-and-braces step — an Authentication Policy Administrator turns on Require CRL validation so that any future CA added without a CRL fails closed instead of open. With both done, the same audit run comes back clean:

PowerShell 7 — Get-CbaTrustStoreReport.ps1 (post-remediation, with -TestCrlReachability)
Connecting to Microsoft Graph (read-only scopes)...
Connected. Tenant: ████████-████-████-████-████████████
  Legacy trust store CAs found : 2
  PKI trust store CAs found    : 0

======================================================================
  ENTRA CBA TRUST STORE REPORT - 31 Jul 2026 15:02
======================================================================
  Total trusted CAs         : 2
  CBA policy state          : enabled
  Default auth mode          : x509CertificateMultiFactor
  Strong-auth rules defined  : 0
  Require CRL validation     : enabled
  CAs exempted from CRL check: 0

  Surface        : Legacy
  Root authority : False
  Issuer         : CN=Contoso Issuing CA 1
  Issuer SKI     : 1A2B3C4D5E6F70819200A1B2C3D4E5F600112233
  CRL URL        : http://pki.contoso.com/issuing1.crl
  Delta CRL URL  : http://pki.contoso.com/issuing1+.crl
  CRL reachable  : HTTP 200
  STATUS         : OK

======================================================================
  SUMMARY
======================================================================
  CAs with no revocation checking (findings): 0
  CAs with an unreachable CRL URL           : 0

RESULT: No revocation-config findings detected.

The exit code is the part worth wiring into automation. The script returns 0 for clean, 2 for findings, and 1 for an error, so a scheduled run in Azure Automation or a Task Scheduler job can alert only when there is genuinely something to fix — and, crucially, will never report clean off the back of a query it could not actually complete.

One thing the "clean" result does not cover: because Entra caches each CRL until its Next Update timestamp, turning on revocation checking does not retroactively kill sessions that a revoked certificate already established. Microsoft's guidance is explicit that when you revoke a certificate for a real incident, you should also revoke the user's existing sessions in Entra ID rather than assume the CRL alone handles it. The audit tells you revocation is now being checked; incident response still owns killing live tokens.

If you run CBA, this is a ten-minute check that is well worth doing this week. A missing CRL distribution point is the kind of gap that stays invisible for exactly as long as nobody revokes a certificate in anger — and then becomes the first question in the post-incident review.

References

Have you actually checked the CRL field on your issuing CA, or are you assuming revocation works because CBA sign-in works? Run the audit, look at that one field, and see what turns up — I'd genuinely like to hear how many tenants find an issuing CA with an empty CRL URL sitting in production.

Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Security
Entra Says "No Risky Users" — But a Real Detection Just…
A risky sign-in fires a real detection, the user passes MFA under a risk-based policy,…
Security
How Many of Your App Registrations Have a Secret Expiring This…
App registration client secrets and certificates expire silently, and nobody tracks the…
Security
Windows LAPS vs Legacy LAPS: The Migration Drift Where Two…
You migrated from legacy Microsoft LAPS to Windows LAPS and the portal looks clean. But…