The posture check catalogue
The nine check categories in pack m365-2026.08.1, what each one looks at, and the anatomy of a single check: identifier, severity, evidence and mappings.
Your posture report shows the checks that found something. It does not show the ones that ran and found nothing, and it does not show the catalogue they came from. This article is that catalogue — the nine categories and what each looks at — followed by the anatomy of a single check, for anyone who wants to know what one actually is before trusting its verdict.
It is a reference rather than a task. If what you want is an order of work, read Severity, blast radius, and what to fix first instead.
How a check is named
Every check has an identifier of the same shape, and once you can read one you can read all of them. It appears in your report, in your evidence bundle, in the database and in any support ticket you raise about a finding, so it is worth thirty seconds.
ZQ - M365 - PRIV - 002
| | | |
| | | +-- sequence, zero-padded to three digits
| | +--------- category token: PRIV AUTH CA HYG EXP
| | DEV APP LOG LIC
| +---------------- the estate being assessed
+---------------------- the vendorThe M365 segment exists because this pack assesses one estate — your Microsoft 365 and the Entra ID directory behind it. A check written later against a different estate would carry a different segment and could not be confused with one of these.
The nine categories
Your report was produced by check pack m365-2026.08.1, which contains 82 checks. Each belongs to exactly one category, and the category is stored as a machine value that the database constrains as well — so a check cannot be filed under a category that does not exist, and a category cannot quietly appear without a schema change.
| Category | Stored value and prefix | Checks | What it looks at |
|---|---|---|---|
| Privilege | privilege · ZQ-M365-PRIV-nnn | 13 | Your directory role assignments: who holds tenant-owning power, how many of them there are, and how well each holder is protected. ZQ-M365-PRIV-013 reports that no Global Administrator could be identified at all. |
| Authentication | authentication · ZQ-M365-AUTH-nnn | 12 | Which second factors your staff have registered, and whether those factors survive a real-time phishing page. ZQ-M365-AUTH-004 is about text messages and phone calls specifically. |
| Access policy | access_policy · ZQ-M365-CA-nnn | 11 | Conditional Access — your sign-in rules. Whether any exist, whether they are switched on rather than sitting in report-only mode (ZQ-M365-CA-005), and whether exclusions have hollowed one out (ZQ-M365-CA-007). |
| Account hygiene | account_hygiene · ZQ-M365-HYG-nnn | 11 | Accounts that exist without doing anything useful, and what they cost you. ZQ-M365-HYG-003 covers disabled accounts still consuming a paid licence. |
| Exposure | exposure · ZQ-M365-EXP-nnn | 9 | Information leaving quietly: a mailbox copying mail outside the business (ZQ-M365-EXP-001), and a rule hiding mail from its own owner (ZQ-M365-EXP-002). |
| Device | device · ZQ-M365-DEV-nnn | 8 | The computers that reach your company data, and how much of each one you can actually see. ZQ-M365-DEV-005 names machines whose operating system no longer receives security updates. |
| Application | application · ZQ-M365-APP-nnn | 7 | Third-party applications holding standing access to company data, and the consent-phishing attack that creates them. All seven are listed in An application can read everyone's email. |
| Logging | logging · ZQ-M365-LOG-nnn | 6 | Whether anything is recording what happens in your tenant (ZQ-M365-LOG-001), and whether that record is reaching Qorionix where it can be acted on (ZQ-M365-LOG-002). |
| Licensing | licensing · ZQ-M365-LIC-nnn | 5 | Money: seats nobody uses, and security capabilities you already pay for and have not switched on (ZQ-M365-LIC-002). |
Thirteen, twelve, eleven, eleven, nine, eight, seven, six and five — 82. That is the number to quote. It is derived from the pack rather than typed into a comment somewhere, deliberately, because a hand-typed number drifts and then ends up on a marketing page.
The tenth category, which is empty
Ten category values are declared. Nine carry checks. The tenth, data_protection, has none in this pack version, and we would rather leave it visible and empty than delete it — an empty category is a question somebody eventually asks, and a deleted one is not.
Why an identifier never changes meaning
Check identifiers are stable and permanent, and one is never reused for a different meaning — not when a check is rewritten, not when its severity changes, and not when it is retired. That is a rule about the identifier, not about the wording: the sentence a check produces can be improved at any time, and frequently is.
The reason is that the identifier outlives the report. A finding is stored with its identifier as plain text rather than as a reference to the pack, precisely so that a finding remains readable after the check that produced it has been retired. If ZQ-M365-PRIV-002 meant one thing in an evidence bundle produced last September and something else in one produced this September, every bundle you had ever handed to an auditor would become unreliable at once — and you would have no way to tell which ones were affected. Two identical identifiers in the pack is a fatal error rather than a warning.
- A gap in the numbering is not a fault. If your report shows
ZQ-M365-APP-005andZQ-M365-APP-007and nothing in between, the missing one either did not fire or was skipped. Numbers are not renumbered to close gaps. - Quoting the identifier is the fastest way to get a useful answer from us. It is unambiguous where a headline is not, which is why How to get help asks for it.
- The pack version matters as much as the identifier. Every run, finding and change set records the pack that produced it. Findings are only comparable across runs at equal pack version, so that is the first thing to check before concluding something got better or worse — see Re-running the assessment and tracking drift.
What a check actually is
A check is a plain function over the inventory that discovery collected. It never calls Microsoft, it never calls a language model, and it never chooses which pile its own remediation lands in — it reports the safety properties of the change it proposes and lets the classifier decide. That separation is what makes the assessment reproducible: run the same check over the same inventory a hundred times and you get the same answer a hundred times.
| Field | What it holds |
|---|---|
ID | The permanent identifier described above. |
Title | The headline, written as the business consequence rather than the control. |
Category | One of the nine above. |
Severity | critical, high, medium, low or info — a default, not a verdict. |
Rationale | Why this matters, in business terms. |
Attack | What an attacker concretely does with it. |
Remediation | The fix, with its cost in time or money stated in the sentence. |
Compliance | The obligations it maps to: NIS2 articles, CIS Microsoft 365 benchmark items, ISO 27001 controls, and GDPR or DORA articles where they apply. |
Requires | The datasets the check must be able to see before it may conclude anything. |
Eval | The function: the comparison it makes, the objects it names, the change it proposes. |
The four prose fields are a build rule rather than an editorial ambition. A check missing its rationale, its attack, its remediation or its compliance mapping does not load, because a finding without them produces a report you cannot act on — the exact failure the whole package exists to prevent. Those four are described from the reader's side in How to read your posture report.
Two real checks, in full
Rather than a mock-up, here are two checks from the pack exactly as they are written.
ZQ-M365-PRIV-001More Global Administrators than the business needs
- Why it matters
- A Global Administrator can delete every mailbox, disable every account, and turn off the logging that would show what happened. Each extra one is another way in, and none of them adds safety.
- What the attacker does
- An attacker only needs one of these accounts. Phishing one of five admins is five times likelier to succeed than phishing one of one.
- The fix
- Two is the right number for a small business: one working admin and one emergency account kept in a safe. Everyone else gets a role scoped to the job they actually do.
The remediation names a target number rather than telling you to reduce the count, because fewer is not an instruction anybody can act on. The check produces nothing at all at two administrators or fewer — no score to improve, no nagging. And it needs exactly one dataset, so it can still run on a tenant where half of discovery failed.
ZQ-M365-LOG-001Nothing is recording what happens in your Microsoft 365
- Why it matters
- Without an audit record, there is no way to find out what happened after something goes wrong — who read which mailbox, what was downloaded, when the intruder first got in. The record has to exist before the incident, not after.
- What the attacker does
- Attackers switch logging off early, precisely so the investigation cannot reconstruct what they did. Where it was never on, they do not have to bother.
- The fix
- Turn on the tenant audit log. It is included in your licence, costs nothing, and changes nothing about how anyone works.
This is the shape of a check about your tenant rather than about anybody in it: blast radius zero, one subject, which is the deliberate exception to the rule that a finding must name real objects. It is also the clearest case of a remediation safe enough to have been applied before you read about it — enable_unified_audit_log is on the closed list of nine described in Done, approve, decide.
Severity is a starting point, not a verdict
The severity written on a check is what it reports in the ordinary case; an evaluator may return a different one when the facts warrant it. ZQ-M365-PRIV-001 above is declared high and escalates itself to critical at five or more Global Administrators, on the reasoning that at five in a small business the role has stopped meaning anything — materially worse than having one spare, rather than merely more of the same. So a severity in your report belongs to that finding about your tenant, not to the check as a fixed label.
How a check declares the data it needs
This is the field that makes an honest report possible and it is the least visible one. Every check names, up front, the datasets it must be able to see. There are eleven, and they are the same keys the stages of discovery record against.
users mfa_registration admin_roles
ca_policies devices signin_logs
mailbox_rules app_consents licenses
groups organizationZQ-M365-PRIV-001 requires admin_roles alone. ZQ-M365-PRIV-002, which cross-references administrators against people who have a mailbox, requires admin_roles and users. ZQ-M365-LOG-001 requires only organization. Some checks deliberately declare nothing at all — ZQ-M365-AUTH-012 is one, because its entire purpose is to report that the multi-factor registration data could not be read, and a check that exists to report a gap must not be disabled by that gap.
The consequence is the single most important rule in the product. If discovery recorded a coverage gap for a dataset a check requires, that check is skipped and reported as skipped — never quietly passed. A check that could not see the data has established nothing, and counting it as a pass is precisely how a Microsoft licence limitation turns into a clean bill of health.
could not be evaluated: the multi-factor authentication registration data was not available for this tenant
What to do next
- When a check cannot run — the five reasons a dataset goes missing, and why a skipped check is better news than a pass that lied.
- Re-running the assessment and tracking drift — what a second run tells you that the first cannot, and when it is worth starting one.