Inforcer compliance and posture reporting: per-tenant Microsoft 365 secure scores, combining them with alignment scores, and the alignedThreshold / semiAlignedThreshold settings that classify each tenant or policy as aligned, semi-aligned, or drifted. Covers portfolio posture roll-ups across the MSP's managed tenants.
Installs into .claude/skills of the current project.
Are you the author of Compliance Reporting?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/wyre-technology-compliance-reporting)
---
name: "Inforcer Compliance Reporting"
description: >
Inforcer compliance and posture reporting: per-tenant Microsoft 365 secure
scores, combining them with alignment scores, and the alignedThreshold /
semiAlignedThreshold settings that classify each tenant or policy as
aligned, semi-aligned, or drifted. Covers portfolio posture roll-ups across
the MSP's managed tenants.
when_to_use: >-
When producing Inforcer security posture or compliance reports for one tenant or the
whole portfolio. Use when: inforcer secure score,
compliance report, posture report, aligned threshold, semi-aligned, drifted classification,
portfolio posture, or secure score per tenant.
---
# Inforcer Compliance Reporting
This skill turns Inforcer's raw signals — secure scores and alignment —
into a posture report. The headline output is a per-tenant
classification (aligned / semi-aligned / drifted) rolled up across the
portfolio, suitable for monthly internal reviews and QBRs.
Read [api-patterns](../api-patterns/SKILL.md) for headers, region, the
envelope, and pagination, and [tenant-management](../tenant-management/SKILL.md)
for resolving tenants to integer Client Tenant IDs. Alignment mechanics
live in [baseline-alignment](../baseline-alignment/SKILL.md).
## Anti-triggers
- **Per-policy drift detail** — this skill produces the classification
and the roll-up; *which* controls diverged is
`inforcer-baseline-alignment`.
- **CIPP's compliance view** — BPA reports, standards compliance, and
domain health are a separate baseline with separate findings; use
`cipp-standards`. Do not blend CIPP and Inforcer scores into one
number.
- **Stale scores before a report** — refreshing the underlying data
means triggering an assessment run, the one write in this plugin; use
`inforcer-assessments`.
## Tools
### `inforcer_secure_scores_get`
Read the Microsoft 365 **secure score** for a tenant — Microsoft's own
security posture measure for the M365 environment.
```
inforcer_secure_scores_get(tenant="Acme")
```
The `tenant` argument accepts a friendly name, a DNS name, an Azure AD
tenant GUID, or the numeric Client Tenant ID; the server resolves the
first three to the numeric id before calling Inforcer.
Secure score is complementary to alignment: alignment says "does this
tenant match *our* baseline?", secure score says "what does Microsoft
think of this tenant's posture overall?". A strong report uses both.
### `inforcer_alignment_scores`
Read the tenant's alignment score against its assigned baseline (the
other half of the posture picture). See
[baseline-alignment](../baseline-alignment/SKILL.md) for details.
```
inforcer_alignment_scores(clientTenantId=1423)
```
## Classification: aligned / semi-aligned / drifted
Alignment classification is **threshold-driven**. Two configurable
settings define the bands:
- `alignedThreshold`
- `semiAlignedThreshold`
A tenant (or an individual policy) is classified by comparing its
alignment value against those thresholds:
| Classification | Condition |
|----------------|-----------|
| **aligned** | value `>= alignedThreshold` |
| **semi-aligned** | value `>= semiAlignedThreshold` **and** `< alignedThreshold` |
| **drifted** | value `< semiAlignedThreshold` |
So the bands are: at or above `alignedThreshold` is **aligned**; in the
window `[semiAlignedThreshold, alignedThreshold)` is **semi-aligned**;
below `semiAlignedThreshold` is **drifted**. Always state the threshold
values you used in the report — a tenant's band is meaningless without
the thresholds that produced it, and changing the thresholds reclassifies
tenants without anything actually changing on the tenant.
```
def classify(value, aligned_threshold, semi_aligned_threshold):
if value >= aligned_threshold:
return "aligned"
if value >= semi_aligned_threshold:
return "semi-aligned"
return "drifted"
```
## Portfolio posture roll-up
For a fleet report:
1. `inforcer_tenants_list` — enumerate managed tenants (page to completion).
2. For each tenant's integer Client Tenant ID, pull
`inforcer_alignment_scores` and `inforcer_secure_scores_get`.
3. Apply the `alignedThreshold` / `semiAlignedThreshold` classification
to the alignment value.
4. Sort tenants drifted-first, then semi-aligned, then aligned, so the
MSP triages the worst posture first.
5. Summarize: counts per band, lowest secure scores, and the tenants
that are both drifted **and** low secure score (the priority list).
| Column | Source |
|--------|--------|
| Alignment score + band | `inforcer_alignment_scores` + thresholds |
| Secure score | `inforcer_secure_scores_get` |
| Classification | computed (aligned / semi-aligned / drifted) |
## Caveats
- This surface is **read-only**. You can report posture but cannot
remediate it, deploy policies, or restore configuration via the API —
those are UI-only. Report findings as recommendations.
- The API is **community-sourced** (no official public docs); the exact
field names for secure score, alignment value, and the threshold
settings are illustrative and credited to
[`royklo/InforcerCommunity`](https://github.com/royklo/InforcerCommunity).
- Don't present a band without its thresholds. If thresholds are
configured differently between runs, a tenant can "change band" with no
real posture change — note the thresholds for reproducibility.
- Secure score and alignment measure different things; don't conflate
them. A high secure score with low alignment means Microsoft is happy
but the tenant diverges from the MSP baseline (and vice versa).
## Related Skills
- [baseline-alignment](../baseline-alignment/SKILL.md) - alignment scores and the per-policy drift detail behind the bands
- [tenant-management](../tenant-management/SKILL.md) - enumerate and resolve tenants for the roll-up
- [assessments](../assessments/SKILL.md) - run an assessment to refresh posture inputs
- [api-patterns](../api-patterns/SKILL.md) - envelope, pagination, region, and the integer-id gotcha