Skip to main content
This is not an official U.S. federal government website. The Federal Modernization Workbook is independent technical analysis. It does not represent the position of, and has not been reviewed or endorsed by, any federal agency.

Federal Modernization Workbook

Chapter 05 — Certificate-Based Authentication Checks

Check the certificate-based authentication configuration behind PIV and CAC sign-in as code, starting from Learn’s CRL page and the PKI trust store and X.509 method APIs, and adding what they leave to you: a measurement of every CRL against the cloud’s own size and download limits, a check of the trusted issuing CAs, the multifactor mapping of the PIV policy OIDs, CRL validation and its exemptions, low-affinity bindings and a Conditional Access policy that requires a phishing-resistant authentication strength, with labs against fixtures and a test tenant.

A revoked card is only revoked if Entra can download the list that says so, in time, every time.

NoteIn this chapter

The checks behind the guide’s Gate 5, “CBA trusts the issuing CAs with CRLs,” and plan task I1.6, the issuing CAs’ CRL sizes checked. You start with Learn’s certificate revocation list page, which sets the limits per cloud, and the Graph resources that hold the trust store and the X.509 certificate method. Then you use examples/hr-lifecycle for what they leave to you: a measurement of every CRL, and a check, CB-01 to CB-13, of the CAs, each CRL against the cloud’s limit, the multifactor mapping, CRL validation and the phishing-resistant strength. Lab 1 runs on a laptop with no tenant; Lab 2 uses a test tenant.

TipNarrated tour
Building HR-Driven Identity, Chapter 05 — Certificate-Based Authentication Checks: narrated tour · 11 minutes · captions from the player's CC button · Download MP4 · All videos
Jump to a slide (18)

Deck · Narrated deck (about 11 minutes, captions) · Script · Captions. Recorded on November 2, 2026 from the approved chapter.

Goal and audience

Goal. By the end of this chapter you can say, from code, whether every CA the card program issues from is trusted with a CRL that Entra can download within the limits of your tenant’s cloud, whether PIV certificates count as multifactor, and whether a Conditional Access policy requires a phishing-resistant strength. You can say, for each rule, whether it is Learn’s limit or the program’s own design.

Audience. Developers who build the credential checks, the PKI and credentialing engineers who run the issuing CAs, and the ISSO who keeps the configuration export. You should read Python. You don’t need a tenant until Lab 2.

Why this gate needs code

The guide’s Gate 5 ties the card’s lifecycle to the person’s: issuance from a joiner record, revocation from a leaver. Revocation only reaches sign-in through the CRL. Book 03 explains why (Chapter 09, Revocation checking), and Book 07 explains the trust store, the bindings and the single-factor and multifactor split (Chapter 06, Entra certificate-based authentication). This chapter doesn’t restate them. It turns them into a check that runs every day, because a CRL grows with every revocation, and the day it crosses the limit is the day sign-in fails for every card from that CA.1

Per-user binding coverage and affinity are the validation kit’s VK-PIV-01 (the validation kit’s README) and the ADM guide’s Gate 6. This chapter checks the tenant’s settings, which VK-PIV-01 doesn’t read.

Which cloud, for this check

Learn gives two sets of CRL limits. For interactive sign-in, a CRL must stay under 20 MB in public Entra ID, which includes GCC, and 45 MB in Azure US Government, which Learn’s FAQ says includes GCC High and DoD; it must download within 10 seconds. The service-side limits are 65 MB and 150 MB.2 config/cba-expected.json holds both sets per cloud name, and the check takes --cloud gcc, gcchigh or dod with no default. Learn writes the limits in MB without saying whether a megabyte is 1,000,000 or 1,048,576 bytes; the configuration reads them as decimal, the stricter reading. The Graph reads go to graph.microsoft.com for GCC and graph.microsoft.us or dod-graph.microsoft.us for GCC High and DoD.3 Certificate-based authentication and Conditional Access are available in Azure for US Government.4

Start with Microsoft’s procedure

What Microsoft gives you

Learn’s CRL page is Microsoft’s procedure and its limits. Without a configured CRL, Entra doesn’t check revocation for that CA. Entra supports one CRL endpoint per CA, HTTP or HTTPS, and recommends HTTP because HTTPS adds latency and its own certificate validation. A configured CRL that can’t be downloaded fails certificate-based authentication for that CA’s certificates, so Learn asks for highly available endpoints, and for CRL validation enforced in policy, with an exemption only as a last resort while troubleshooting.5 The setup page lists the same prerequisite: each CA has a CRL from an internet-facing URL.6

Graph holds the configuration in three places, all in v1.0:

  • the PKI-based trust store, a list of certificateBasedAuthPki objects, each with certificateAuthorities of type certificateAuthorityDetail, which carry certificateRevocationListUrl, certificateAuthorityType (root or intermediate), thumbprint and expirationDateTime;7 8 9
  • the X.509 certificate authentication method, x509CertificateAuthenticationMethodConfiguration, with authenticationModeConfiguration (a default mode and rules that map an issuer or a policy OID to x509CertificateMultiFactor), crlValidationConfiguration (a state and the exempted CAs’ subject key identifiers) and certificateUserBindings;10 11 12 13 14
  • the authentication strength policies, whose allowedCombinations use the authenticationMethodModes values, and the Conditional Access policies that reference them.15 16

Learn’s authentication strengths page says the built-in phishing-resistant strength allows Windows Hello for Business or platform credential, FIDO2 and certificate-based authentication (multifactor).17

What it leaves to you

Each row is pinned by a test in tests/test_credentials_separation_drift.py.

What Learn gives Why it matters What examples/hr-lifecycle adds
The limits, in prose Nobody measures the CRL until sign-in fails cba_check.py measure downloads each CRL and records bytes and seconds; check compares them with the cloud’s limit (test_the_crl_limit_follows_the_cloud)
One limit per cloud A GCC tenant sized to the GCC High limit passes a CRL that fails The limit comes from --cloud, never a default (test_the_crl_limit_follows_the_cloud)
“A CRL that can’t be downloaded fails CBA” An unreachable endpoint looks like a missing measurement A download error or a missing measurement is a Finding, not a skip (test_an_unreachable_or_unmeasured_crl_is_a_finding)
The trust store as Graph objects A renewed CA with a new thumbprint is silently missing Each issuing CA the card program uses is named by thumbprint in config/cba-expected.json (test_cba_fixture_raises_each_rule)
Mode rules by issuer or policy OID PIV certificates sign in as single-factor and fail the strength CB-09 checks the program’s PIV policy OIDs map to multifactor (test_cba_fixture_raises_each_rule)
CRL validation and exemptions An exemption made while troubleshooting stays forever Each exempted CA is a Warn until it’s removed (test_cba_fixture_raises_each_rule)
Strengths and policies, separately The phishing-resistant strength exists but no enforced policy requires it CB-10 looks for an enabled policy for all users and all resources whose strength allows only phishing-resistant combinations; a report-only policy doesn’t count (test_a_compliant_configuration_is_clean)

The verdict. Keep Learn’s limits as the configuration’s values and Learn’s objects as the check’s inputs. The code measures and compares; it never changes the configuration.

The code: what examples/hr-lifecycle adds

python/cba_check.py has two commands, and reads the exports graph_export.py --task cba-read writes.

The measurement

measure takes a file with one CRL URL per line, downloads each once, and writes crl-measurements.csv with the bytes, the seconds and any error. A failed download is recorded, not raised: the unreachable CRL is the finding. For labs, a local path is read as a file. Run it from the network that represents the internet-facing path Entra uses, not from inside the PKI’s own network (design guidance).

The check

Rule Severity What it flags Source
CB-01 Finding; Warn An intermediate CA with no CRL configured (Finding); a root CA with none (Warn) Learn: no CRL, no revocation check18
CB-02 Warn A CRL endpoint that isn’t HTTP Learn recommends HTTP19
CB-03 Finding A CRL over the cloud’s interactive size limit Learn20
CB-04 Finding A CRL that couldn’t be downloaded, or took more than 10 seconds Learn21
CB-05 Warn A CRL over 80% of the limit Design guidance (warnPercent)
CB-06 Finding A configured CRL with no measurement Design guidance: measure every CRL
CB-07 Finding The X.509 certificate method isn’t enabled Learn22
CB-08 Warn CRL validation isn’t enabled, or a CA is exempted Learn recommends enforcing it and exempting only to troubleshoot23
CB-09 Finding A PIV policy OID not mapped to multifactor, with a single-factor default Learn’s mode rules;24 the program’s OIDs
CB-10 Finding No enabled policy for all users and resources requires a phishing-resistant strength SCuBA MS.AAD.3.1v1;25 Learn’s strengths26
CB-11 Warn A CA certificate that expires within 90 days Design guidance (caExpiryWarnDays)
CB-12 Finding An issuing CA the card program uses isn’t in the trust store Design guidance
CB-13 Warn A low-affinity binding field (PrincipalName, RFC822Name) configured The validation kit’s affinity table; ADM Gate 6’s decision

A root CA with no CRL configured is a Warn, not a Finding: a root that issues only CA certificates may publish none. Learn’s prerequisite is wider, “each CA has a CRL,” and Learn says Entra checks the CRLs up the chain to the root, so the warning asks you to confirm the root’s revocation path, and Lab 2 checks it (verification log, row 14).27 28

The read needs three permissions, each the least-privileged for its call:

Call Least-privileged permission Delegated role
List certificateBasedAuthPki, and each one’s CAs PublicKeyInfrastructure.Read.All29 30 Authentication Administrator or Privileged Authentication Administrator
Get the X.509 certificate method Policy.Read.AuthenticationMethod31 Global Reader or Authentication Policy Administrator
List authentication strength policies Policy.Read.AuthenticationMethod32 Conditional Access Administrator, Security Administrator or Security Reader
List Conditional Access policies Policy.Read.All33 Global Reader or Security Reader

The code reads the PKI-based trust store, not the older organization/{id}/certificateBasedAuthConfiguration, whose Learn pages name Global Administrator as the only role for a delegated read.34

The tests

Five tests cover this chapter: every rule on the fixture, the limit by cloud, an unreachable or unmeasured CRL, a compliant configuration that comes back clean, and the measurement against a fake opener. With the other chapters’, 57 pytest tests pass under Python 3.10 or later, with no package, tenant or network.

ImportantIllustrative code

The commands below run the example against a fictional tenant’s exports and fictional CRL files. They show what the code does, not that a tenant returns the same shapes. Review the code and run Lab 2 in a test tenant before it reports on production.

Lab 1: fixtures, no tenant

You need Python 3.10 or later. Work in examples/hr-lifecycle.

NoteEvery command in Lab 1

Every command in this lab, in order, from examples/hr-lifecycle. Each step below says what it does and what to look for.

# Step 1: List the calls and permissions
python python/graph_export.py --task cba-read --list

# Step 2: Measure the fixture CRLs
python python/cba_check.py measure --urls tests/fixtures/ch05/crl-urls.txt --out out/ch05/crl-measurements.csv

# Step 3: Check the fictional tenant for GCC
python python/cba_check.py check --cloud gcc --exports tests/fixtures/ch05/exports --crl tests/fixtures/ch05/crl-measurements.csv --expected config/cba-expected.json --as-of 2026-11-01 --out out/ch05/check

# Step 4: Check the same tenant for GCC High
python python/cba_check.py check --cloud gcchigh --exports tests/fixtures/ch05/exports --crl tests/fixtures/ch05/crl-measurements.csv --expected config/cba-expected.json --as-of 2026-11-01 --out out/ch05/check-gcchigh

# Step 5: Run the tests
python -m pytest tests -q

# After the steps
rm -rf out
  1. List the calls and permissions:

    python python/graph_export.py --task cba-read --list
    Task cba-read: Policy.Read.All, Policy.Read.AuthenticationMethod, PublicKeyInfrastructure.Read.All
      GET /directory/publicKeyInfrastructure/certificateBasedAuthConfigurations  [PublicKeyInfrastructure.Read.All]
      GET /directory/publicKeyInfrastructure/certificateBasedAuthConfigurations/{pkiId}/certificateAuthorities  [PublicKeyInfrastructure.Read.All]
      GET /policies/authenticationMethodsPolicy/authenticationMethodConfigurations/x509Certificate  [Policy.Read.AuthenticationMethod]
      GET /policies/authenticationStrengthPolicies  [Policy.Read.AuthenticationMethod]
      GET /identity/conditionalAccess/policies  [Policy.Read.All]

    Terminal window showing python python/graph_export.py --task cba-read --list and what it printed

    What the terminal shows, run on the kit’s fixtures (the same output as text)
  2. Measure the fixture CRLs:

    python python/cba_check.py measure --urls tests/fixtures/ch05/crl-urls.txt --out out/ch05/crl-measurements.csv
             4,096 bytes    0.000 s  tests/fixtures/ch05/crl/piv-ca1.crl
             8,192 bytes    0.000 s  tests/fixtures/ch05/crl/piv-ca2.crl
                 0 bytes    0.000 s  tests/fixtures/ch05/crl/missing.crl  FileNotFoundError
    Measured 3 CRL(s) -> out/ch05/crl-measurements.csv

    Terminal window showing python python/cba_check.py measure --urls tests/fixtures/ch05/crl-urls.txt --… and what it printed

    What the terminal shows, run on the kit’s fixtures (the same output as text)

    The times on your machine will differ. The missing file is recorded with its error, not raised. The check in the next step reads tests/fixtures/ch05/crl-measurements.csv instead, which holds measurements of the fictional tenant’s own CRL URLs, one of them 18.5 million bytes and 11.4 seconds.

  3. Check the fictional tenant for GCC:

    python python/cba_check.py check --cloud gcc --exports tests/fixtures/ch05/exports --crl tests/fixtures/ch05/crl-measurements.csv --expected config/cba-expected.json --as-of 2026-11-01 --out out/ch05/check
    Cloud gcc: interactive CRL limit 20,000,000 bytes, download within 10 s
    CBA: 5 Finding, 7 Warn, 0 Info
      CB-01 Finding: Contoso Example Legacy Intermediate: no CRL configured: Entra doesn't check revocation for this CA
      CB-04 Finding: Contoso Example PIV Issuing CA 2 (renewed): CRL took 11.4 s to download; the limit is 10 s
      CB-09 Finding: authentication mode: PIV policy OID(s) 2.16.840.1.101.3.2.1.48.11 not mapped to multifactor, and the default is single-factor
      CB-10 Finding: Conditional Access: no enabled policy for all users and all resources requires a phishing-resistant authentication strength (SCuBA MS.AAD.3.1v1)
      CB-12 Finding: Contoso Example PIV Issuing CA 2: issuing CA the card program uses isn't in the trust store
      CB-01 Warn: Contoso Example PIV Root CA: root CA with no CRL configured; Learn asks for a CRL on each CA; confirm the root's revocation path
      CB-02 Warn: Contoso Example PIV Issuing CA 2 (renewed): CRL endpoint https://pki.contoso.example/crl/piv-ca2.crl isn't HTTP; Learn recommends HTTP
      CB-05 Warn: Contoso Example PIV Issuing CA 2 (renewed): CRL is 18,500,000 bytes, over 80% of the gcc interactive limit
      CB-08 Warn: CRL validation: CBA doesn't require a CRL from every CA (crlValidationConfiguration isn't enabled)
      CB-08 Warn: CA 5A5B5C5D5E5F60616263646566676869: exempted from CRL validation; allowed only while its CRL is fixed, with an end date
      CB-11 Warn: Contoso Example Legacy Intermediate: CA certificate expires 2026-12-15
      CB-13 Warn: username bindings: low-affinity binding fields configured (PrincipalName); align with the affinity decision (ADM Gate 6) and VK-PIV-01

    Terminal window showing python python/cba_check.py check --cloud gcc --exports tests/fixtures/ch05/ex… and what it printed

    What the terminal shows, run on the kit’s fixtures (the same output as text)

    The exit code is 2. Read the story in the fixture: CA 2 was renewed, so the thumbprint the card program expects is gone (CB-12) and the renewed CA’s CRL is large, slow and on HTTPS. The tenant’s mode rule maps the wrong OID (CB-09), and the phishing-resistant policy is still report-only, so the enforced policy requires only the MFA strength (CB-10).

  4. Check the same tenant for GCC High:

    python python/cba_check.py check --cloud gcchigh --exports tests/fixtures/ch05/exports --crl tests/fixtures/ch05/crl-measurements.csv --expected config/cba-expected.json --as-of 2026-11-01 --out out/ch05/check-gcchigh
    Cloud gcchigh: interactive CRL limit 45,000,000 bytes, download within 10 s
    CBA: 5 Finding, 6 Warn, 0 Info

    Terminal window showing python python/cba_check.py check --cloud gcchigh --exports tests/fixtures/ch0… and what it printed

    What the terminal shows, run on the kit’s fixtures (the same output as text)

    The same 18.5 million bytes is under 80% of the Azure Government limit, so CB-05 drops away. The 11.4-second download is a Finding in every cloud.

  5. Run the tests:

    python -m pytest tests -q

    Terminal window showing python -m pytest tests -q and what it printed

    What the terminal shows, run on the kit’s fixtures (the same output as text)

Expected result: 57 passed. Delete out when you’re done:

rm -rf out

Terminal window showing rm -rf out and what it printed

What the terminal shows, run on the kit’s fixtures (the same output as text)

Lab 2: test tenant

Not run by the authors. Use a test tenant with certificate-based authentication configured for a test CA, never production. Work in examples/hr-lifecycle. You’ll replace: <graph-token> (a bearer token for graph.microsoft.com issued to the reader app), <pki-id> (the PKI container’s ID, from the list in step 2), <crl-url-1> and <crl-url-2> (the test CAs’ CRL URLs, one per CA), <ca-name> and <ca-thumbprint> (an issuing CA of the test PKI), <piv-policy-oid> (the policy OID of the test PKI’s PIV authentication certificates), <cloud> (the test tenant’s cloud: gcc, gcchigh or dod) and <today> (today’s date, yyyy-mm-dd).

NoteEvery command in Lab 2

Every command in this lab, in order, from examples/hr-lifecycle. Each step below says what it does and what to look for.

# Step 2: Export the configuration
export HRLC_GRAPH_TOKEN='<graph-token>'
curl -s -H "Authorization: Bearer $HRLC_GRAPH_TOKEN" https://graph.microsoft.com/v1.0/directory/publicKeyInfrastructure/certificateBasedAuthConfigurations
python python/graph_export.py --task cba-read --cloud gcc --param pkiId=<pki-id> --out exports/cba

# Step 2: Export the configuration
python -c "import json; print('x509 objects:', len(json.load(open('exports/cba/x509-method.json'))['value'])); [print(c['displayName'], c.get('certificateRevocationListUrl')) for c in json.load(open('exports/cba/pki-cas.json'))['value']]"

# Step 3: Measure the real CRLs
printf '%s\n' '<crl-url-1>' '<crl-url-2>' > my-crl-urls.txt
python python/cba_check.py measure --urls my-crl-urls.txt --out out/cba-test/crl-measurements.csv

# Step 4: Check
python -c "import json; d=json.load(open('config/cba-expected.json')); d['issuingCas'] = [{'displayName': '<ca-name>', 'thumbprint': '<ca-thumbprint>'}]; d['multifactorPolicyOids'] = ['<piv-policy-oid>']; json.dump(d, open('my-cba-expected.json', 'w'), indent=2)"
python python/cba_check.py check --cloud <cloud> --exports exports/cba --crl out/cba-test/crl-measurements.csv --expected my-cba-expected.json --as-of <today> --out out/cba-test/check

# Step 6: Back it out
rm -rf exports out my-crl-urls.txt my-cba-expected.json
  1. Register the reader app with a certificate, and grant the three application permissions from Lab 1, step 1, with admin consent, and nothing else.

  2. Export the configuration. With a token for the reader app in HRLC_GRAPH_TOKEN, list the PKI containers, then export the task with the container’s ID:

    export HRLC_GRAPH_TOKEN='<graph-token>'
    curl -s -H "Authorization: Bearer $HRLC_GRAPH_TOKEN" https://graph.microsoft.com/v1.0/directory/publicKeyInfrastructure/certificateBasedAuthConfigurations
    python python/graph_export.py --task cba-read --cloud gcc --param pkiId=<pki-id> --out exports/cba

    Check that x509-method.json holds one object and that each CA in pki-cas.json carries certificateRevocationListUrl as the fixture does. This prints the count and each CA’s URL:

    python -c "import json; print('x509 objects:', len(json.load(open('exports/cba/x509-method.json'))['value'])); [print(c['displayName'], c.get('certificateRevocationListUrl')) for c in json.load(open('exports/cba/pki-cas.json'))['value']]"
  3. Measure the real CRLs. Put each CA’s CRL URL in a file, one per line (add a line for each further CA), and run measure from outside the agency network:

    printf '%s\n' '<crl-url-1>' '<crl-url-2>' > my-crl-urls.txt
    python python/cba_check.py measure --urls my-crl-urls.txt --out out/cba-test/crl-measurements.csv

    Record the run’s date with the file.

  4. Check. Copy config/cba-expected.json with the CA thumbprints and PIV policy OIDs replaced by the test PKI’s (add an entry to issuingCas for each further issuing CA), and run check with --cloud set to the test tenant’s cloud:

    python -c "import json; d=json.load(open('config/cba-expected.json')); d['issuingCas'] = [{'displayName': '<ca-name>', 'thumbprint': '<ca-thumbprint>'}]; d['multifactorPolicyOids'] = ['<piv-policy-oid>']; json.dump(d, open('my-cba-expected.json', 'w'), indent=2)"
    python python/cba_check.py check --cloud <cloud> --exports exports/cba --crl out/cba-test/crl-measurements.csv --expected my-cba-expected.json --as-of <today> --out out/cba-test/check
  5. Prove revocation. Revoke a test user’s certificate, wait for the CA’s next CRL publication, and sign in with it. Entra should refuse it with the revoked-certificate error Learn lists.35 Record the revocation time, the CRL’s publication time and the refused sign-in.

  6. Back it out. Remove the permissions, delete the reader app and its certificate, and reissue the test user’s certificate if you need it again. Then delete exports and out, with the lab’s two files:

    rm -rf exports out my-crl-urls.txt my-cba-expected.json

Verified facts

Item Value US Government clouds Stage Source
CRL limits Interactive 20 MB (public, includes GCC) and 45 MB (Azure US Government, includes GCC High and DoD); 10-second download; service limits 65 MB and 150 MB Applies, with the larger limits GA 36
CRL behavior No CRL, no revocation check; one endpoint, HTTP or HTTPS, HTTP recommended; a configured CRL that can’t be downloaded fails CBA; CRLs checked up to 10 CAs toward the root — GA 37
List certificateBasedAuthPki; list its certificateAuthorities PublicKeyInfrastructure.Read.All; Authentication Administrator or Privileged Authentication Administrator L4 and L5 v1.0 38 39
certificateAuthorityDetail certificateRevocationListUrl, certificateAuthorityType, thumbprint, expirationDateTime, issuerSubjectKeyIdentifier — v1.0 40
Get X.509 certificate method Policy.Read.AuthenticationMethod; Global Reader or Authentication Policy Administrator L4 and L5 (not 21Vianet) v1.0 41
X.509 method properties authenticationModeConfiguration (rules by issuerSubject or policyOID), crlValidationConfiguration, certificateUserBindings (PrincipalName, RFC822Name, SubjectKeyIdentifier, SHA1PublicKey) — v1.0 42 43 44 45
List authentication strength policies Policy.Read.AuthenticationMethod; allowedCombinations from authenticationMethodModes L4 and L5 v1.0 46 47
List Conditional Access policies Policy.Read.All — v1.0 48
Legacy certificateBasedAuthConfiguration Organization.Read.All; Global Administrator is the only delegated role L4 and L5 v1.0 49
CBA and Conditional Access Available in Azure for US Government Available GA 50

Places Learn says nothing or differs, recorded so a later edit doesn’t loosen the code:

  • Megabytes. Learn writes “20 MB” and “45 MB” without a byte count. The configuration uses decimal megabytes, the stricter reading. Learn also says it is reviewing the limits and plans to remove them.51
  • Two pages, two limits. Learn’s CBA-with-federation page still gives a single 20 MB limit with no cloud split; the CRL page gives both. The code follows the CRL page for the cloud split and applies 20 MB to GCC either way.52 53
  • Root CAs. Learn’s prerequisite is a CRL for each CA; the check warns on a root with none rather than failing it (verification log, row 14).
  • Priority. Learn says Entra uses the binding “with the highest priority” without saying whether that is the largest or the smallest number.54 CB-13 flags any low-affinity field rather than guessing the order.

Federal requirements and evidence

This chapter helps prove the guide’s Gate 5; its requirements table is the source, and the federal framework crosswalk lists every federal source.

Requirement KSI What this code shows What the ISSO keeps
NIST SP 800-53 IA-2(12), acceptance of PIV credentials, and IA-5(2), public key-based authentication (Moderate) None lists IA-2(12); KSI-IAM-APM, KSI-IAM-ELP, KSI-SVC-ASM (IA-5(2)) Every issuing CA trusted, with a CRL Entra can download in time, and revocation enforced The cba-read export and the check’s findings.json and manifest.json, dated; each CRL measurement
CISA SCuBA MS.AAD.3.1v1 and MS.AAD.3.6v1, phishing-resistant MFA (BOD 25-01 required) KSI-IAM-APM, as Book 04, Chapter 10 maps it An enabled policy requires a phishing-resistant strength, and PIV certificates count as multifactor The check’s CB-09 and CB-10 rows, beside the ScubaGear report
FIPS 201-3, termination of the card None: not an SP 800-53 control A revoked card is refused, because its CA’s CRL is reachable and enforced Lab 2’s refused sign-in, the revocation record and the CRL that published it
NIST SP 800-63-4, authenticator assurance None: not an SP 800-53 control The certificate counts at the strength the agency claims The mode rules in the export

Each scripted step in the labs, and each file the code writes, with the evidence it leaves:

Lab step What it runs or writes Requirement KSI Evidence
Lab 1, step 1 graph_export.py --task cba-read --list AC-6, least privilege: GET calls only KSI-IAM-ELP The printed list, and config/calls.json as reviewed
Lab 1, step 2 cba_check.py measure, writing crl-measurements.csv IA-5(2): revocation data Entra can download in time KSI-IAM-APM, KSI-SVC-ASM Each CRL’s size, time and error, dated; this file has no manifest, so file it with the check that reads it
Lab 1, steps 3 and 4 cba_check.py check (CB-01 to CB-13) for GCC and for GCC High, writing findings.json IA-5(2); SC-17 for the trusted CAs (CB-11, CB-12); MS.AAD.3.1v1 and MS.AAD.3.6v1 (CB-09, CB-10) KSI-IAM-APM, KSI-SVC-ASM; KSI-SVC-ASM; KSI-IAM-APM out/ch05/check/findings.json, with the cloud, tenant and date in manifest.json
Lab 1, steps 3 and 4 manifest.json AU-9; SI-7 KSI-MLA-OSM; KSI-SVC-VRI A SHA-256 per file, written once
Lab 1, step 5 python -m pytest tests -q CM-3(2) (design guidance) KSI-CMT-VTD 57 passed, kept with the change
Lab 1, clean-up rm -rf out None: fixture output isn’t evidence — —
Lab 2, step 2 curl the PKI containers; graph_export.py --task cba-read, writing pki-containers.json, pki-cas.json, x509-method.json, auth-strengths.json, ca-policies.json and export.json; print the CAs IA-5(2); SC-17; AC-6 for GET only KSI-IAM-APM, KSI-SVC-ASM; KSI-SVC-ASM; KSI-IAM-ELP exports/cba/export.json and the five call files, dated
Lab 2, step 3 Write my-crl-urls.txt; measure, writing out/cba-test/crl-measurements.csv IA-5(2) KSI-IAM-APM, KSI-SVC-ASM The real CRLs’ measurements, taken from outside the agency network
Lab 2, step 4 Write my-cba-expected.json; check into out/cba-test/check IA-5(2); SC-17; MS.AAD.3.1v1 and MS.AAD.3.6v1 KSI-IAM-APM, KSI-SVC-ASM; KSI-SVC-ASM; KSI-IAM-APM out/cba-test/check/findings.json and its manifest
Lab 2, step 6 Remove the permissions and the reader app; rm -rf the lab files AC-6: no reader permissions left after the test KSI-IAM-ELP The app’s deletion in the directory audit log

KSIs are FedRAMP 20x indicators for cloud service providers: the agency authorizes its own system and lines this evidence up with what its providers report against them, and it doesn’t report KSIs itself (Book 00, Appendix B). Each KSI shown lists the row’s control among its related SP 800-53 controls on FedRAMP’s page;55 which file supports which indicator is the program’s mapping (design guidance). Controls the guide’s table doesn’t name (AC-6, AU-9, CM-3(2), SC-17, SI-7) are in the Moderate baseline (Book 13, Appendix A; Book 14, Appendix A).

Dangers

Danger What happens The guard
A CRL that grows past the limit Every card from that CA fails sign-in CB-03 and the early warning CB-05, every run
An unreachable or slow CRL endpoint Same outage, from the network side CB-04; Learn’s highly available HTTP endpoints
A CA without a CRL Revoked cards still sign in CB-01
A renewed CA not added New cards don’t sign in, and nobody knows why CB-12 by thumbprint, CB-11 before expiry
A troubleshooting exemption that stays Revocation is off for that CA CB-08 lists every exemption, every run
PIV mapped as single-factor Users meet MFA with a password plus something else, not the card CB-09
A phishing-resistant policy left in report-only The requirement exists on paper CB-10 counts only enabled policies
Measuring from inside the PKI’s network The measurement passes while Entra’s path fails Run measure from an internet-facing vantage point (design guidance)

Checklist

Back to top

Footnotes

  1. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  2. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  3. Microsoft Learn, “Microsoft Graph national cloud deployments,” https://learn.microsoft.com/graph/deployments (read November 1, 2026; carried from Book 19, Chapter 02).↩︎

  4. Microsoft Learn, “Microsoft Entra feature availability,” https://learn.microsoft.com/entra/identity/authentication/feature-availability (read November 1, 2026; carried from the HR-driven identity implementation guide’s verification log).↩︎

  5. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  6. Microsoft Learn, “Set up Microsoft Entra certificate-based authentication,” prerequisites, https://learn.microsoft.com/entra/identity/authentication/how-to-certificate-based-authentication (read November 1, 2026).↩︎

  7. Microsoft Learn, “List certificateBasedAuthPki objects,” permissions and national clouds, https://learn.microsoft.com/graph/api/publickeyinfrastructureroot-list-certificatebasedauthconfigurations?view=graph-rest-1.0 (read November 1, 2026).↩︎

  8. Microsoft Learn, “List certificateAuthorityDetail objects,” permissions and national clouds, https://learn.microsoft.com/graph/api/certificatebasedauthpki-list-certificateauthorities?view=graph-rest-1.0 (read November 1, 2026).↩︎

  9. Microsoft Learn, “certificateAuthorityDetail resource type,” properties, https://learn.microsoft.com/graph/api/resources/certificateauthoritydetail?view=graph-rest-1.0 (read November 1, 2026).↩︎

  10. Microsoft Learn, “x509CertificateAuthenticationMethodConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificateauthenticationmethodconfiguration?view=graph-rest-1.0 (read November 1, 2026).↩︎

  11. Microsoft Learn, “Get x509CertificateAuthenticationMethodConfiguration,” permissions and national clouds, https://learn.microsoft.com/graph/api/x509certificateauthenticationmethodconfiguration-get?view=graph-rest-1.0 (read November 1, 2026).↩︎

  12. Microsoft Learn, “x509CertificateRule resource type” and “x509CertificateAuthenticationModeConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificaterule?view=graph-rest-1.0 (read November 1, 2026).↩︎

  13. Microsoft Learn, “x509CertificateCRLValidationConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificatecrlvalidationconfiguration?view=graph-rest-1.0 (read November 1, 2026).↩︎

  14. Microsoft Learn, “x509CertificateUserBinding resource type,” https://learn.microsoft.com/graph/api/resources/x509certificateuserbinding?view=graph-rest-1.0 (read November 1, 2026).↩︎

  15. Microsoft Learn, “List authenticationStrengthPolicies,” permissions and national clouds, https://learn.microsoft.com/graph/api/authenticationstrengthroot-list-policies?view=graph-rest-1.0 (read November 1, 2026).↩︎

  16. Microsoft Learn, “authenticationMethodModes enum type,” https://learn.microsoft.com/graph/api/resources/authenticationmethodmodes?view=graph-rest-1.0 (read November 1, 2026).↩︎

  17. Microsoft Learn, “Conditional Access authentication strengths,” built-in authentication strengths, https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths (read November 1, 2026).↩︎

  18. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  19. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  20. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  21. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  22. Microsoft Learn, “x509CertificateAuthenticationMethodConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificateauthenticationmethodconfiguration?view=graph-rest-1.0 (read November 1, 2026).↩︎

  23. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  24. Microsoft Learn, “x509CertificateRule resource type” and “x509CertificateAuthenticationModeConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificaterule?view=graph-rest-1.0 (read November 1, 2026).↩︎

  25. Cybersecurity and Infrastructure Security Agency, “BOD 25-01: Implementing Secure Practices for Cloud Services Required Configurations,” MS.AAD.3.1v1 and MS.AAD.3.6v1, https://www.cisa.gov/resources-tools/services/bod-25-01-implementing-secure-practices-cloud-services-required-configurations (read November 1, 2026; carried from the HR-driven identity implementation guide).↩︎

  26. Microsoft Learn, “Conditional Access authentication strengths,” built-in authentication strengths, https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths (read November 1, 2026).↩︎

  27. Microsoft Learn, “Set up Microsoft Entra certificate-based authentication,” prerequisites, https://learn.microsoft.com/entra/identity/authentication/how-to-certificate-based-authentication (read November 1, 2026).↩︎

  28. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  29. Microsoft Learn, “List certificateBasedAuthPki objects,” permissions and national clouds, https://learn.microsoft.com/graph/api/publickeyinfrastructureroot-list-certificatebasedauthconfigurations?view=graph-rest-1.0 (read November 1, 2026).↩︎

  30. Microsoft Learn, “List certificateAuthorityDetail objects,” permissions and national clouds, https://learn.microsoft.com/graph/api/certificatebasedauthpki-list-certificateauthorities?view=graph-rest-1.0 (read November 1, 2026).↩︎

  31. Microsoft Learn, “Get x509CertificateAuthenticationMethodConfiguration,” permissions and national clouds, https://learn.microsoft.com/graph/api/x509certificateauthenticationmethodconfiguration-get?view=graph-rest-1.0 (read November 1, 2026).↩︎

  32. Microsoft Learn, “List authenticationStrengthPolicies,” permissions and national clouds, https://learn.microsoft.com/graph/api/authenticationstrengthroot-list-policies?view=graph-rest-1.0 (read November 1, 2026).↩︎

  33. Microsoft Learn, “List policies” (conditionalAccessRoot), https://learn.microsoft.com/graph/api/conditionalaccessroot-list-policies?view=graph-rest-1.0 (read November 1, 2026; carried from the validation kit’s VK-CA-01 and Building Privileged Access, Chapter 02).↩︎

  34. Microsoft Learn, “Get certificateBasedAuthConfiguration” and “List certificateBasedAuthConfigurations,” permissions, https://learn.microsoft.com/graph/api/certificatebasedauthconfiguration-get?view=graph-rest-1.0 (read November 1, 2026).↩︎

  35. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  36. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  37. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  38. Microsoft Learn, “List certificateBasedAuthPki objects,” permissions and national clouds, https://learn.microsoft.com/graph/api/publickeyinfrastructureroot-list-certificatebasedauthconfigurations?view=graph-rest-1.0 (read November 1, 2026).↩︎

  39. Microsoft Learn, “List certificateAuthorityDetail objects,” permissions and national clouds, https://learn.microsoft.com/graph/api/certificatebasedauthpki-list-certificateauthorities?view=graph-rest-1.0 (read November 1, 2026).↩︎

  40. Microsoft Learn, “certificateAuthorityDetail resource type,” properties, https://learn.microsoft.com/graph/api/resources/certificateauthoritydetail?view=graph-rest-1.0 (read November 1, 2026).↩︎

  41. Microsoft Learn, “Get x509CertificateAuthenticationMethodConfiguration,” permissions and national clouds, https://learn.microsoft.com/graph/api/x509certificateauthenticationmethodconfiguration-get?view=graph-rest-1.0 (read November 1, 2026).↩︎

  42. Microsoft Learn, “x509CertificateAuthenticationMethodConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificateauthenticationmethodconfiguration?view=graph-rest-1.0 (read November 1, 2026).↩︎

  43. Microsoft Learn, “x509CertificateRule resource type” and “x509CertificateAuthenticationModeConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificaterule?view=graph-rest-1.0 (read November 1, 2026).↩︎

  44. Microsoft Learn, “x509CertificateCRLValidationConfiguration resource type,” https://learn.microsoft.com/graph/api/resources/x509certificatecrlvalidationconfiguration?view=graph-rest-1.0 (read November 1, 2026).↩︎

  45. Microsoft Learn, “x509CertificateUserBinding resource type,” https://learn.microsoft.com/graph/api/resources/x509certificateuserbinding?view=graph-rest-1.0 (read November 1, 2026).↩︎

  46. Microsoft Learn, “List authenticationStrengthPolicies,” permissions and national clouds, https://learn.microsoft.com/graph/api/authenticationstrengthroot-list-policies?view=graph-rest-1.0 (read November 1, 2026).↩︎

  47. Microsoft Learn, “authenticationMethodModes enum type,” https://learn.microsoft.com/graph/api/resources/authenticationmethodmodes?view=graph-rest-1.0 (read November 1, 2026).↩︎

  48. Microsoft Learn, “List policies” (conditionalAccessRoot), https://learn.microsoft.com/graph/api/conditionalaccessroot-list-policies?view=graph-rest-1.0 (read November 1, 2026; carried from the validation kit’s VK-CA-01 and Building Privileged Access, Chapter 02).↩︎

  49. Microsoft Learn, “Get certificateBasedAuthConfiguration” and “List certificateBasedAuthConfigurations,” permissions, https://learn.microsoft.com/graph/api/certificatebasedauthconfiguration-get?view=graph-rest-1.0 (read November 1, 2026).↩︎

  50. Microsoft Learn, “Microsoft Entra feature availability,” https://learn.microsoft.com/entra/identity/authentication/feature-availability (read November 1, 2026; carried from the HR-driven identity implementation guide’s verification log).↩︎

  51. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  52. Microsoft Learn, “Microsoft Entra certificate-based authentication Certificate Revocation List (CRL),” revocation process, setup guidance and FAQ, https://learn.microsoft.com/entra/identity/authentication/concept-certificate-based-authentication-certificate-revocation-list (read November 1, 2026).↩︎

  53. Microsoft Learn, “Get started with certificate-based authentication in Microsoft Entra ID with federation,” requirements, https://learn.microsoft.com/entra/identity/authentication/certificate-based-authentication-federation-get-started (read November 1, 2026).↩︎

  54. Microsoft Learn, “x509CertificateUserBinding resource type,” https://learn.microsoft.com/graph/api/resources/x509certificateuserbinding?view=graph-rest-1.0 (read November 1, 2026).↩︎

  55. FedRAMP, “Key Security Indicators,” FedRAMP Consolidated Rules for 2026, indicator titles and “Related SP 800-53 Controls,” including the mapping updates of October 13, 2026, https://www.fedramp.gov/2026/reference/key-security-indicators/ (read November 2, 2026; the indicator IDs are carried from Book 13, Appendix A and Book 14, Chapter 03).↩︎