Skip to content
russ.tools

Conditional Access Analyser help

Guidance from this tool's documentation.

Quick start

  1. Export your policies (see below), or select Load sample to see how it reads.
  2. Paste the JSON into the box. A single policy, an array, or a whole Graph response all work.
  3. Policies shows each one as who / what / when / then.
  4. Gaps runs the checklist over the whole set.
  5. Nothing is uploaded and nothing is kept — close the tab and it is gone.

Getting the JSON

  • Graph Explorer — run GET /identity/conditionalAccess/policies and paste the whole response, @odata.context and all.
  • PowerShellGet-MgIdentityConditionalAccessPolicy | ConvertTo-Json -Depth 10. Use a generous depth; the default truncates the nested conditions into System.Object[] and the policy becomes unreadable.
  • A single policy — copy one object out of either of the above.

All three shapes are accepted, and the tool tells you which one it read.

Reading who / what / when / then

A policy is four independent decisions, and the export interleaves them. Splitting them out is most of the value:

  • Who — users, groups, roles and guest types, include and exclude. Exclusions are highlighted, because they are usually where the surprise is.
  • What — cloud apps, user actions, authentication contexts.
  • When — client app types, platforms, locations, sign-in and user risk, device filters. A policy with no conditions says "always", which is worth seeing stated.
  • Then — the grant controls, and crucially the operator. OR means any single control satisfies the policy; AND means all of them must. "MFA or compliant device" and "MFA and compliant device" differ by one word in the JSON and by a great deal in practice.

GUIDs are resolved to names where the tool knows them — 135 directory roles and the common first-party applications. An id it cannot name is shown as the raw GUID rather than hidden, because an unnameable exclusion is exactly the thing worth looking up.

State is shown as a badge, because it changes what everything else means. enabled, disabled and enabledForReportingButNotEnforced are three very different things, and the last one — report-only — is evaluated and logged but never blocks or challenges anyone.

What the gap checklist looks for

Each finding carries a severity and names the policies that triggered it:

  • Legacy authentication never blocked by an enabled policy
  • A blocking policy that targets all users with no exclusions at all — no break-glass account left outside it
  • No policy requiring MFA for administrators
  • Policies sitting in report-only or disabled
  • No policy requiring a compliant or hybrid-joined device
  • All users and all apps in one enabled policy with no exclusions
  • No sign-in frequency or browser-persistence session control
  • A privileged directory role excluded from an enabled policy

What this cannot tell you

This is a heuristic review of the JSON you pasted, not a tenant assessment. It has no access to your tenant, so it cannot see:

  • policies you did not paste — a clean result on three policies says nothing about the other twelve
  • who actually holds a directory role, or whether an excluded group is empty
  • whether a named location, device filter or authentication strength is configured the way its name suggests
  • sign-in logs, so it cannot tell you what any policy has actually done

Treat every finding as a prompt to go and check something. A finding is not a vulnerability, and an empty report is not a clean bill of health.

Back to Conditional Access Analyser