Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

## [3.4.1] - 2026-06-13

**Theme:** Maintenance & data hygiene. Corrects a false-automation claim (`ENTRA-SSPR-002`), restores CIS M365 v6 §5.2.4.1 coverage as `ENTRA-SSPR-003`, de-jargons the `StrykerReadiness` collector to `CriticalExposure` (M365-Assess [#968](https://github.com/Galvnyz/M365-Assess/issues/968)), materializes the deferred [#347](https://github.com/Galvnyz/CheckID/issues/347) CIS M365 v6 phase-1 enrichment fields, and adopts the initial ADR set ([#399](https://github.com/Galvnyz/CheckID/issues/399)). Patch release — data corrections only; no schema, registry-field, or module-API shape change (the collector value rename is downstream-coordinated and non-breaking).

### Fixed

- **`ENTRA-SSPR-002` false-automation claim corrected.** The "SSPR enabled for admin accounts" check has been claiming `hasAutomatedCheck: true` despite no supported Microsoft Graph endpoint existing for the SSPR enablement scope (only the undocumented `main.iam.ad.ext.azure.com` internal API). Confirmed by inspecting Galvnyz/M365-Assess: no collector references this CheckID; the related ENTRA-SSPR-001 collector at `Entra/EntraPasswordAuthChecks.ps1` self-acknowledges the gap (`CurrentValue: 'Not auto-measurable via Microsoft Graph'`). Flipped to `hasAutomatedCheck: false` with portal-only remediation and a `notes` block documenting the no-supported-endpoint state. Per [ADR-0005](docs/adr/0005-coverage-gaps-without-graph-api.md). Stale parent path also corrected from `Protection >` to `Entra ID >` per [ADR-0002](docs/adr/0002-portal-path-vocabulary.md).
- **CIS M365 v6 §5.2.4.1 coverage restored as `ENTRA-SSPR-003`.** PR [#397](https://github.com/Galvnyz/CheckID/pull/397) removed the §5.2.4.1 (All-users SSPR enablement) mapping from `ENTRA-SSPR-001` during the MFA Registration Campaign rebadge with the comment "a future ENTRA-SSPR-002 will measure actual SSPR enablement" — but the existing ENTRA-SSPR-002 measures admin-only SSPR, a different control. Filed `ENTRA-SSPR-003` as the All-users SSPR enablement entry, `hasAutomatedCheck: false` (same no-supported-endpoint situation as SSPR-002), with the CIS 5.2.4.1 mapping restored. Per [ADR-0005](docs/adr/0005-coverage-gaps-without-graph-api.md): file uncoverable controls as manual entries with full framework mappings rather than skip them or claim false automation.

### Changed

- **Collector `StrykerReadiness` renamed to `CriticalExposure`** (surfaced by [Galvnyz/M365-Assess#968](https://github.com/Galvnyz/M365-Assess/issues/968)). The `StrykerReadiness` codename read as insider jargon to report viewers; `CriticalExposure` ties the collector to the report's "Critical exposure" section (renamed in M365-Assess #962). Affects the 9 checks that carry it: `ENTRA-ROLEGROUP-001`, `ENTRA-STALEADMIN-001`, `ENTRA-BREAKGLASS-001`, `ENTRA-SYNCADMIN-001`, `ENTRA-APPS-002`, `CA-EXCLUSION-001`, `INTUNE-RBAC-001`, `INTUNE-MAA-001`, `INTUNE-WIPEAUDIT-001`. Renamed across the source mapping (`data/scf-check-mapping.json`), the generated `data/registry.json` (targeted value edit — `collector` is a verbatim pass-through, so the result is identical to a rebuild for this field; a full `Build-Registry.py` rerun was not run since it requires the upstream `scf.db`), the `collector` enum in `data/registry.schema.json`, the `$knownCollectors` allow-list in `tests/registry-integrity.Tests.ps1`, the `_COLLECTOR_TAGS` key in `scripts/Build-Registry.py` (tags `["identity", "privileged-access"]` preserved), and the `data/scf-migration-review.csv` review artifact. **Breaking for downstream collector consumers:** M365-Assess gates sync on a collector allow-list (`controls/sync-scope.json` → `Import-ControlRegistry`) and drops checks whose collector is unknown, so consumers (M365-Assess, StrykerScan, M365-Remediate) must accept `CriticalExposure` in lockstep — update `sync-scope.json`, the `Show-CheckProgress.ps1` family/display/order maps, the emitting collector script, and the collector-family docs before or atomically with this release, tracked on M365-Assess #968. The `StrykerScan` consumer repo name is a separate identifier and is untouched; the report's `Stryker Readiness` *domain chip* is generated independently in M365-Assess (`Get-CheckDomain`) and is a distinct fix noted on #968.
- **Collector `StrykerReadiness` renamed to `CriticalExposure`** (surfaced by [Galvnyz/M365-Assess#968](https://github.com/Galvnyz/M365-Assess/issues/968)). The `StrykerReadiness` codename read as insider jargon to report viewers; `CriticalExposure` ties the collector to the report's "Critical exposure" section (renamed in M365-Assess #962). Affects the 9 checks that carry it: `ENTRA-ROLEGROUP-001`, `ENTRA-STALEADMIN-001`, `ENTRA-BREAKGLASS-001`, `ENTRA-SYNCADMIN-001`, `ENTRA-APPS-002`, `CA-EXCLUSION-001`, `INTUNE-RBAC-001`, `INTUNE-MAA-001`, `INTUNE-WIPEAUDIT-001`. Renamed across the source mapping (`data/scf-check-mapping.json`), the generated `data/registry.json` (targeted value edit — `collector` is a verbatim pass-through, so the result is identical to a rebuild for this field; a full `Build-Registry.py` rerun was not run since it requires the upstream `scf.db`), the `collector` enum in `data/registry.schema.json`, the `$knownCollectors` allow-list in `tests/registry-integrity.Tests.ps1`, the `_COLLECTOR_TAGS` key in `scripts/Build-Registry.py` (tags `["identity", "privileged-access"]` preserved), and the `data/scf-migration-review.csv` review artifact. **Non-breaking — already coordinated downstream:** M365-Assess [PR #982](https://github.com/Galvnyz/M365-Assess/pull/982) (merged) made its sync allow-list (`controls/sync-scope.json`), `Show-CheckProgress` maps, and report `criticalExposure` flag accept **both** `StrykerReadiness` and `CriticalExposure`, so the next `sync-checkid` run after a CheckID release flips the value with no flag-day. M365-Assess drops the legacy name and refreshes its `COMPLIANCE.md`/`COVERAGE.md` collector lists in a follow-up. The `StrykerScan` consumer repo name is a separate identifier and is untouched; the report's `Stryker Readiness` *domain chip* is generated independently in M365-Assess (`Get-CheckDomain`) and is a distinct fix noted on #968.
- **CIS M365 v6 phase-1 enrichment fields materialized in `registry.json`** (refs [#347](https://github.com/Galvnyz/CheckID/issues/347)). The v3.4.0 release shipped the schema + ingestion infrastructure for `sectionNumber`, `assessmentStatus`, `cisSafeguardsByVersion`, `defaultValue`, and `references` fields with a CHANGELOG note flagging that a `Build-CisM365Crosswalk.py` + `Build-Registry.py` rerun was needed to materialize them. That rebuild had not been committed; this commit's registry rebuild materializes the fields onto the 156 CIS M365 v6 entries that carry them.

### Documentation
Expand Down
2 changes: 1 addition & 1 deletion CheckID.psd1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@{
# Module metadata
RootModule = 'CheckID.psm1'
ModuleVersion = '3.4.0'
ModuleVersion = '3.4.1'
GUID = 'a3b7c4d5-1e2f-4a5b-8c9d-0e1f2a3b4c5d'
Author = 'Galvnyz'
CompanyName = 'Galvnyz'
Expand Down
4 changes: 2 additions & 2 deletions data/registry.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schemaVersion": "3.4.0",
"dataVersion": "2026-05-06",
"schemaVersion": "3.4.1",
"dataVersion": "2026-06-13",
"generatedFrom": "data/scf-check-mapping.json + SecFrame/SCF/scf.db + data/scf-framework-map.json + data/az-assess-source-checks.json",
"checks": [
{
Expand Down
2 changes: 1 addition & 1 deletion scripts/Build-Registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
SCRIPT_DIR = Path(__file__).parent
REPO_ROOT = SCRIPT_DIR.parent

SCHEMA_VERSION = "3.4.0"
SCHEMA_VERSION = "3.4.1"


# ---------------------------------------------------------------------------
Expand Down
Loading