TenantAtlas/specs/424-security-defaults-content-backed-comparable-support/spec.md
ahmido 2cd512915a feat: complete spec 424 security defaults content-backed comparable support (#491)
Implements spec 424 with comparable renderable capture/readiness changes and supporting tests/spec artifacts.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #491
2026-07-01 14:41:24 +00:00

40 KiB

Feature Specification: Spec 424 - Security Defaults Content-Backed Comparable Support

Feature Branch: 424-security-defaults-content-backed-comparable-support Created: 2026-06-30 Status: Draft Input: User-provided draft "Spec 424 - Security Defaults Content-Backed Comparable Support", prepared through spec-kit-next-best-prep.

Preparation Metadata

  • Selected candidate: Spec 424 - Security Defaults Content-Backed Comparable Support.
  • Source location: User attachment /Users/ahmeddarrazi/.codex/attachments/5bd37778-05ff-4b65-b5fc-407deb4d5000/pasted-text.txt.
  • Why selected: The active auto-prep queue in docs/product/spec-candidates.md remains empty, but the user explicitly promoted this bounded Coverage v2 follow-up. Spec 421 proved Conditional Access comparable/renderable support and deferred Security Defaults because it was not content-backed. Spec 423 is now completed, leaving Security Defaults as the precise Entra denominator blocker before any later certified Entra compare pack can be credible.
  • Roadmap relationship: Aligns with the roadmap's Microsoft governance expansion, evidence/coverage hardening, provider-boundary discipline, and security posture direction. This package is not auto-selected from the candidate queue; it is a user-promoted P0 Coverage v2 safety slice.
  • Close alternatives deferred: Management-report runtime validation, governance artifact lifecycle retention, provider readiness productization, cross-domain indicator follow-through, system-panel browser fixture work, and first governed AI consumer remain manual-promotion backlog items. Entra certification, restore/apply, customer reports, Review Pack output, full Entra coverage, and additional Entra resource types remain later explicit specs.
  • Related completed-spec guardrail: specs/414-tcm-first-coverage-core-cutover/, specs/415-generic-content-backed-capture/, specs/417-canonical-identity-engine/, specs/418-coverage-v2-operator-surface/, specs/419-m365-tcm-workload-registry-expansion/, specs/420-m365-generic-evidence-coverage-pack/, specs/421-entra-core-comparable-renderable-pack/, and specs/423-security-compliance-readiness-pack/ contain completed/validated signals and are read-only dependency context. Do not rewrite them, normalize their close-out history, or strip task/browser/review evidence.
  • Repo-truth preflight result: Current code has a securityDefaults registry row in ResourceTypeRegistry::m365RepresentativeDefinitions(), but it is registry-only/out-of-scope, uses existing source_class = tcm, has default_coverage_level = detected, default_evidence_state = not_captured, default_claim_state = internal_only, and restore_tier = not_restorable. CoverageSourceContractResolver has no securityDefaults mapping, config/graph_contracts.php has no Security Defaults contract, CoverageIdentityStrategyRegistry has no securityDefaults strategy, and EntraComparablePayloadNormalizer supports only conditionalAccessPolicy. SupportedScopeResolver includes securityDefaults in Entra planning scope, but no certified or restore-ready Security Defaults scope may be activated in this spec.
  • Smallest viable implementation slice: Add the minimum repo-conventional source contract, capture eligibility, singleton-safe evidence capture proof, identity strategy, typed normalizer, comparator, render summary, Claim Guard hardening, redaction proof, RBAC/scope proof, and tests needed to promote only securityDefaults to internal/operator content-backed, comparable, and renderable support. If the source contract cannot be proven safely, the implementation must leave Security Defaults blocked with a stable missing-contract/unsupported result and must not promote support.
  • Candidate Selection Gate: PASS for a direct user-provided P0 candidate with repo-truth deviations documented below.

Draft-To-Repo Deviations

  • The draft uses restore_tier = compare_only; current repo truth has not_restorable, preview_only, and restorable. This spec uses not_restorable as the repo-equivalent no-restore posture and forbids adding a new restore tier unless the proportionality review is amended.
  • The draft allows resource_class = security_setting or tenant_setting; current repo truth has ResourceClass::Configuration. This spec keeps configuration unless implementation proves a new resource class has a current-release behavioral consequence and amends the proportionality review first.
  • The draft lists capture_blocked_source_unavailable; current repo outcomes are captured, capture_blocked_missing_contract, capture_blocked_permission, capture_blocked_beta, capture_blocked_unsupported, and capture_failed. This spec uses existing outcomes plus stable reason codes unless a new outcome passes the constitution proportionality gate.
  • The draft allows source class tcm or graph_v1_fallback. Current repo truth has securityDefaults seeded as a TCM planning row but no real contract. Implementation may switch the row to graph_v1_fallback only if the canonical graph contract and capture path prove a real v1 content source. It must not promote a beta-only source to later-certifiable support.

Spec Candidate Check (mandatory - SPEC-GATE-001)

  • Problem: Security Defaults is part of the later Entra certified compare denominator, but TenantPilot currently treats securityDefaults as registry-only/out-of-scope and cannot capture, compare, or render it as content-backed evidence.
  • Today's failure: A later Entra compare claim would either omit a core security setting or imply Security Defaults support that repo truth does not prove. Operators cannot answer whether Security Defaults is enabled without raw provider inspection or unsafe overclaim.
  • User-visible improvement: Authorized internal operators can see Security Defaults as content-backed, comparable, and renderable on the existing Coverage v2 path once real evidence exists, while certification, restore, customer-ready, and full Entra claims remain blocked.
  • Smallest enterprise-capable version: Support exactly securityDefaults through existing Coverage v2 capture/evidence/identity/redaction/Claim Guard/read-model paths. No new Entra dashboard, no restore, no certification, no customer output, no additional Entra types.
  • Explicit non-goals: No Entra certification, no restore/apply, no Review Pack/report/PDF/export output, no customer-facing Entra claim, no Application/Service Principal/Role Definition/Administrative Unit support, no new Entra table family, no separate Security Defaults engine, no live docs fetch, no tenant_id, no v1 compatibility.
  • Permanent complexity imported: One focused source contract mapping if safe, one bounded identity strategy, Security Defaults typed normalization/compare/render helper extensions or sibling helpers, Claim Guard phrase coverage, redaction tests, and focused feature/browser-if-rendered tests. No new persisted entity, broad status family, route, dashboard, or cross-domain framework is planned.
  • Why now: Spec 421 proved Conditional Access comparable/renderable support and deferred Security Defaults. Security Defaults is the next concrete blocker before any later Entra denominator can be certified or described honestly.
  • Why not local: A local Security Defaults parser or ad-hoc Graph call would bypass Coverage v2 source contracts, evidence persistence, provider scope, identity, redaction, OperationRun, and Claim Guard truth. The existing Coverage v2 path is the narrowest correct implementation.
  • Approval class: Core Enterprise.
  • Red flags triggered: Adds typed support and source-contract mapping for one provider-specific singleton. Defense: the slice is limited to one concrete security setting, plugs into existing Coverage v2 machinery, and prevents a concrete future overclaim.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
  • Decision: approve as a narrow, evidence-gated support closure.

Spec Scope Fields (mandatory)

  • Scope: workspace plus managed-environment scoped Coverage v2 evidence for one Entra resource type, securityDefaults.
  • Primary Routes: Existing internal/operator Coverage v2 readiness/inspect route only if rendered data changes. No new route, navigation entry, customer route, report, download, dashboard, wizard, or action is in scope.
  • Data Ownership: Existing Coverage v2 TenantConfigurationResourceType, TenantConfigurationResource, and TenantConfigurationResourceEvidence rows remain owned by workspace_id, managed_environment_id, and same-scope provider_connection_id for provider-sourced records. Provider-native Microsoft tenant IDs remain metadata only.
  • RBAC: Existing Coverage v2 read authorization applies. Non-member or wrong workspace/environment access is deny-as-not-found (404). A member missing the required view capability receives 403. Capture start permissions remain existing tenant-configuration capture permissions; readonly users must not start capture.

No Legacy / No Backward Compatibility Constraint (mandatory)

TenantPilot is pre-production for this feature.

  • Compatibility posture: canonical Coverage v2 extension.
  • Legacy aliases, fallback readers, hidden routes, duplicate UI, old labels, or historical fixtures kept?: no.
  • Why clean replacement is safe now: This is a new support closure over Coverage v2. No customer contract requires Coverage v1 adapters, dual writes, fallback readers, legacy claim labels, or old fixture preservation.

UI Surface Impact (mandatory - UI-COV-001)

Does this spec add, remove, rename, or materially change any reachable UI surface?

  • No UI surface impact
  • Existing page changed
  • New page/route added
  • Navigation changed
  • Filament panel/provider surface changed
  • New modal/drawer/wizard/action added
  • New table/form/state added
  • Customer-facing surface changed
  • Dangerous action changed
  • Status/evidence/review presentation changed
  • Workspace/environment context presentation changed

Expected impact is data-driven presentation on the existing Coverage v2 internal/operator readiness and inspect surface when Security Defaults comparable/renderable summaries become visible through existing read-model output. No new UI files are required by this spec. If implementation needs Blade, Livewire, Filament Resource/Page/Widget, route, navigation, action, or other runtime UI file edits, the plan/tasks must be amended first with the exact affected files, browser proof, and Human Product Sanity criteria.

UI/Productization Coverage (mandatory when UI Surface Impact is not "No UI surface impact")

  • Route/page/surface: Existing Coverage v2 readiness/resource/evidence inspection surface and inspect detail disclosure.
  • Current or new page archetype: Technical Annex / read-only evidence inspection.
  • Design depth: Internal/Hidden with Product Surface proof if rendered output changes.
  • Repo-truth level: repo-verified existing surface from Spec 418.
  • Existing pattern reused: Existing Coverage v2 read model, internal/operator inspect flow, badge/status patterns, and Spec 421 Entra render/compare family.
  • New pattern required: none.
  • Screenshot required: no standalone screenshot artifact required by prep; focused browser proof required if rendered output changes.
  • Page audit required: no full page audit; focused existing-surface browser smoke is sufficient unless implementation changes runtime UI files, routes, navigation, page structure, actions, or panel/provider surface.
  • Customer-safe review required: yes for wording boundaries; no customer route or output may be activated.
  • Dangerous-action review required: no mutating/destructive action is in scope.
  • Coverage files updated or explicitly not needed:
    • docs/ui-ux-enterprise-audit/route-inventory.md
    • docs/ui-ux-enterprise-audit/design-coverage-matrix.md
    • docs/ui-ux-enterprise-audit/page-reports/...
    • docs/ui-ux-enterprise-audit/strategic-surfaces.md
    • docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md
    • docs/ui-ux-enterprise-audit/unresolved-pages.md
    • N/A - existing internal surface only; update coverage artifacts only if runtime UI files/routes/navigation change
  • No-impact rationale when applicable: N/A.

Product Surface Impact (mandatory for UI-affecting specs)

Reference: docs/product/standards/product-surface-contract.md.

  • Product Surface Contract applies?: yes, for data-driven rendered status/evidence/readiness changes on the existing Coverage v2 surface.
  • Page archetype: Technical Annex.
  • Primary user question: Is Security Defaults content-backed, comparable, renderable, and safe for later certification inclusion?
  • Primary action: Inspect.
  • Surface budget result: pass if limited to the existing read-only surface and inspect disclosure; exception required if implementation adds a new page, dashboard, action, customer output, or more than one primary decision flow.
  • Technical Annex / deep-link demotion: Raw payloads, normalized JSON, source IDs, provider IDs, evidence hashes, OperationRun links, permission context, source contract keys, and unsupported fields remain hidden, demoted, or diagnostics-only.
  • Canonical status vocabulary: Product-facing labels must use existing canonical states such as Ready, Needs attention, Blocked, and Unknown, or existing internal Coverage v2 labels. Do not expose certified, restore-ready, customer-ready, full Entra coverage, or M365 certified.
  • Visible complexity impact: neutral or decreased if the existing inspect surface gains a concise summary; increased complexity requires a documented exception.
  • Product Surface exceptions: none planned.

Browser Verification Plan (mandatory)

  • Browser proof required?: yes if Security Defaults summaries, comparable/renderable state, or readiness text render on the existing Coverage v2 surface; otherwise no.
  • No-browser rationale: N/A - no rendered UI surface changed only if implementation proves no rendered output changes.
  • Focused path when required: Existing Coverage v2 readiness/operator route with a seeded workspace, managed environment, provider connection, and Security Defaults content-backed evidence row.
  • Primary interaction to execute: Load the existing route as an authorized operator, inspect the Security Defaults row, verify enabled/disabled/unknown summary, comparable/renderable state, no raw payload, no secrets, no certified/restore/customer claim, and no console/Livewire/Filament errors.
  • Console, Livewire, Filament, network, and 500-error checks: planned when browser proof is required.
  • Full-suite failure triage: unrelated browser/full-suite failures may be documented only after focused proof is green.

Human Product Sanity Check (mandatory)

  • Required?: yes if rendered output changes; no if no rendered output changes.
  • No-human-sanity rationale: N/A only with exact no-rendered-change proof.
  • Reviewer questions: Can an operator tell whether Security Defaults is enabled? Is it clear this is internal comparable/renderable support, not certification or restore readiness? Are technical details demoted? Is there one dominant inspect action? Is visible complexity not worse?
  • Planned result location: implementation report / PR close-out.

Product Surface Merge Gate Checklist (mandatory)

  • No-legacy posture or approved exception recorded.
  • Product Surface Impact is completed.
  • Browser proof is required if rendered output changes, or N/A - no rendered UI surface changed must be justified.
  • Human Product Sanity is required if rendered output changes, or N/A must be justified.
  • Product Surface exceptions are documented or none.
  • Implementation report will state Livewire v4 compliance, provider registration location, global search posture, destructive/high-impact action posture, asset strategy, tests/browser result, deployment impact, visible complexity outcome, and no completed-spec rewrite assertion.

Cross-Cutting / Shared Pattern Reuse (mandatory)

  • Cross-cutting feature?: yes.
  • Interaction class(es): source contract, evidence capture, typed compare/render, status/evidence presentation, claim safety.
  • Systems touched: ResourceTypeRegistry, CoverageSourceContractResolver, config/graph_contracts.php, GenericContentEvidenceCaptureService, CoverageIdentityStrategyRegistry, CanonicalIdentityResolver, EntraComparablePayloadNormalizer, EntraCoverageComparator, EntraRenderableSummaryBuilder, CoverageV2ReadinessReadModel, CoveragePayloadRedactor, and ClaimGuard.
  • Existing pattern(s) to extend: Spec 415 generic content-backed capture, Spec 417 canonical identity, Spec 421 Entra comparable/renderable helpers, existing Coverage v2 read model, existing Claim Guard.
  • Shared contract / presenter / builder / renderer to reuse: Coverage v2 source/evidence/identity/read-model path, redactor, Claim Guard, and Entra comparable/renderable family.
  • Why the existing shared path is sufficient or insufficient: Sufficient as the integration boundary. It lacks only Security Defaults source mapping, identity strategy, typed semantics, and claim phrase coverage.
  • Allowed deviation and why: A focused singleton handling path is allowed only if the existing list capture path cannot safely capture the source payload; it must remain inside the existing Coverage v2 capture/source contract machinery.
  • Consistency impact: Security Defaults support must align with existing coverage levels, evidence states, identity states, capture outcomes, claim states, redaction, RBAC behavior, and Product Surface demotion.
  • Review focus: Verify no endpoint guessing, no direct HTTP/Graph SDK bypass, no raw payload default display, no customer claims, no restore/certify action, no mini-platform, no new tables, and no tenant_id.

OperationRun UX Impact (mandatory when touched)

  • Touches OperationRun start/completion/link UX?: no new start/completion/link UX.
  • Shared OperationRun UX contract/layer reused: Existing tenant-configuration capture OperationRun behavior remains the execution path if capture is run.
  • Delegated start/completion UX behaviors: N/A - no new capture start action, toast, DB notification, or run detail link is introduced.
  • Local surface-owned behavior that remains: Existing diagnostic OperationRun references, if present, remain secondary/internal and authorized.
  • Queued DB-notification policy: N/A - no new queued notification.
  • Terminal notification path: Existing OperationRun lifecycle mechanism only.
  • Exception required?: none.

Provider Boundary / Platform Core Check (mandatory)

  • Shared provider/platform boundary touched?: yes.
  • Boundary classification: mixed. Coverage v2 evidence, identity, claim, redaction, and read-model semantics are platform-core; Security Defaults and Graph field names are provider-owned typed adapter details.
  • Seams affected: source contract mapping, source class, resource type defaults, identity strategy, typed payload field mapping, compare/render interpretation, claim wording.
  • Neutral platform terms preserved or introduced: workspace, managed environment, provider connection, resource type, evidence state, coverage level, identity state, claim state, compare result, render summary.
  • Provider-specific semantics retained and why: securityDefaults and enabled-state semantics are necessary for this Microsoft Entra support slice. They must stay bounded to source metadata and typed helper code, not platform ownership truth.
  • Why this does not deepen provider coupling accidentally: No provider-native tenant ID ownership, no Entra table family, no Entra dashboard, no provider framework, no customer claim activation, and no restore/certify support.
  • Follow-up path: Later Entra certified compare pack, restore/apply, customer reporting, and additional Entra resource types require separate specs.

UI / Surface Guardrail Impact (mandatory when operator-facing surfaces are changed)

Surface / Change Operator-facing surface change? Native vs Custom Shared-Family Relevance State Layers Touched Exception Needed? Low-Impact / N/A Note
Existing Coverage v2 readiness / inspect surface data yes, data-driven if summaries render Native Filament existing surface Coverage v2 evidence/readiness family page/detail no No new route/action/navigation planned

Decision-First Surface Role (mandatory when operator-facing surfaces are changed)

Surface Decision Role Human-in-the-loop Moment Immediately Visible for First Decision On-Demand Detail / Evidence Why This Is Primary or Why Not Workflow Alignment Attention-load Reduction
Existing Coverage v2 readiness / inspect surface Tertiary Evidence / Diagnostics Release/operator review of Security Defaults support resource name, enabled/disabled/unknown summary, coverage/evidence/identity/claim state, blockers raw/normalized payload, source metadata, unsupported fields, evidence hash, OperationRun link Not primary; it supports internal evidence inspection and release review Follows existing Coverage v2 internal review flow Reduces raw-payload reading for Security Defaults

Audience-Aware Disclosure (mandatory when operator-facing surfaces are changed)

Surface Audience Modes In Scope Decision-First Default-Visible Content Operator Diagnostics Support / Raw Evidence One Dominant Next Action Hidden / Gated By Default Duplicate-Truth Prevention
Coverage v2 readiness / inspect operator-MSP, support-platform Security Defaults enabled state, evidence/identity/claim state, blocker summary source contract, unsupported fields, source version, permission summary raw payload, normalized JSON, permission context, source keys Inspect raw/support detail and OperationRun diagnostics Security Defaults state appears once; no duplicate certified/readiness claim

UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)

Surface Action Surface Class Surface Type Likely Next Operator Action Primary Inspect/Open Model Row Click Secondary Actions Placement Destructive Actions Placement Canonical Collection Route Canonical Detail Route Scope Signals Canonical Noun Critical Truth Visible by Default Exception Type / Justification
Coverage v2 readiness List / Table / Report Read-only registry/evidence inspection Inspect Security Defaults evidence Existing inspect affordance existing behavior not required none existing route inspect disclosure workspace + managed environment Security Defaults enabled state, coverage level, evidence state, identity state, claim state none

Operator Surface Contract (mandatory when operator-facing surfaces are changed)

Surface Primary Persona Decision / Operator Action Supported Surface Type Primary Operator Question Default-visible Information Diagnostics-only Information Status Dimensions Used Mutation Scope Primary Actions Dangerous Actions
Coverage v2 readiness / inspect internal operator / release reviewer Verify Security Defaults can be interpreted safely Technical Annex Is Security Defaults content-backed and comparable/renderable? enabled state, coverage/evidence/identity/claim state, blockers raw payload, normalized JSON, source metadata, unsupported fields, OperationRun coverage level, evidence state, identity state, claim state read-only Inspect none

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no. Security Defaults remains Coverage v2 evidence truth on existing resource/evidence rows.
  • New persisted entity/table/artifact?: no planned.
  • New abstraction?: no new broad abstraction planned; a focused source contract mapping, identity strategy entry, and typed helper extension are expected.
  • New enum/state/reason family?: no planned. Existing CaptureOutcome, CoverageLevel, EvidenceState, IdentityState, ClaimState, RestoreTier, and compare labels should be reused. New reason codes may be stable strings only when they change blocker explanation.
  • New cross-domain UI framework/taxonomy?: no.
  • Current operator problem: Security Defaults is a core Entra setting required for later denominator truth, but current repo truth cannot capture or explain it.
  • Existing structure is insufficient because: The existing Coverage v2 path is correct, but lacks the one source contract, identity strategy, and typed Security Defaults semantics needed to avoid raw-payload inspection and overclaim.
  • Narrowest correct implementation: Extend only existing Coverage v2 source, capture, identity, Entra typed compare/render, read-model, redaction, and Claim Guard paths for securityDefaults.
  • Ownership cost: Focused tests and maintenance of one source contract, one identity strategy, and one typed mapping.
  • Alternative intentionally rejected: New Security Defaults engine/dashboard or broad Entra pack, because that would import routes, persistence, and product claims outside the current blocker.
  • Release truth: Current-release internal support closure, not customer/certification/restore readiness.

Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)

  • Test purpose / classification: Unit for source contract, normalizer, comparator, render summary, Claim Guard, redaction; Feature for capture/evidence, RBAC/scope, no certification/restore/customer claim, no tenant_id, no mini-platform; Browser only if rendered output changes.
  • Validation lane(s): focused Sail/Pest fast-feedback and confidence lanes; browser lane only when rendered output changes; PostgreSQL lane only if implementation touches JSONB/schema/index behavior, which is not planned.
  • Why this classification and these lanes are sufficient: The behavior is service-level and existing-surface rendering over existing persistence. Unit/feature tests prove business truth; browser proof proves rendered Product Surface safety if needed.
  • New or expanded test families: focused Spec 424 TenantConfiguration tests; no broad heavy-governance family.
  • Fixture / helper cost impact: Minimal workspace, managed environment, provider connection, OperationRun, and fake Security Defaults payload fixtures. No live Graph, TCM, Microsoft docs, or network calls.
  • Heavy-family visibility / justification: none planned.
  • Special surface test profile: Technical Annex / existing Coverage v2 surface if rendered output changes.
  • Standard-native relief or required special coverage: Existing internal surface only; focused browser proof instead of full page audit unless UI files/routes/navigation change.
  • Reviewer handoff: Confirm lane fit, fake payload minimality, no live provider calls, no broad Entra scope, and exact proof commands.
  • Budget / baseline / trend impact: none expected.
  • Escalation needed: none if scope stays limited to Security Defaults support closure.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec424
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=ClaimGuard
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • git diff --check
    • focused browser test command if rendered output changes

User Scenarios & Testing (mandatory)

User Story 1 - Capture Real Security Defaults Evidence (Priority: P1)

As an internal operator preparing an Entra compare baseline, I need Security Defaults captured through the existing Coverage v2 source-contract path so later comparison is based on real content, not a registry placeholder.

Independent Test: Given a valid source contract and fake provider response for Security Defaults, capture persists raw and normalized payloads, payload hash, provider scope, OperationRun link, and content-backed evidence. Given no valid contract, capture produces a blocked outcome and no fake evidence.

Acceptance Scenarios:

  1. Given no approved source contract mapping exists, when capture requests securityDefaults, then the result is capture_blocked_missing_contract or the repo-equivalent blocked outcome with a stable reason code and no evidence row.
  2. Given an approved v1 source contract and successful fake provider response, when capture runs through the existing tenant-configuration capture operation, then one Security Defaults evidence row is persisted as content-backed.
  3. Given provider permission is missing, when capture runs, then the result is blocked or failed safely with sanitized context and no fake content-backed evidence.

User Story 2 - Compare Enabled-State Changes Deterministically (Priority: P1)

As an operator reviewing two captured states, I need Security Defaults enabled-state changes to be classified consistently so a material security posture change is never hidden as metadata noise.

Independent Test: Compare output detects false-to-true, true-to-false, null-to-known, added, removed, unchanged, volatile-only, redacted, and unsupported-field cases with stable ordering and critical importance for enabled-state changes.

User Story 3 - Render an Operator-Safe Security Defaults Summary (Priority: P1)

As an operator, I need a concise Security Defaults summary that answers whether it is enabled, content-backed, comparable, renderable, and safe for later certification inclusion without exposing raw Graph payloads.

Independent Test: Render output shows enabled/disabled/unknown, evidence state, identity state, claim state, last captured time, and blockers while hiding raw payload, normalized JSON, permission context, tokens, secrets, provider response bodies, and source keys by default.

User Story 4 - Prevent Overclaim, Restore, and Customer Output (Priority: P1)

As a release reviewer, I need Claim Guard, RBAC, Product Surface, and no-mini-platform proof so Security Defaults support cannot be mistaken for Entra certification, restore readiness, full coverage, or customer-ready proof.

Independent Test: Claim Guard allows only scoped internal/operator content-backed/comparable/renderable claims and blocks certified, restore-ready, customer-ready, full Entra, 100 percent, broad M365, report/review-pack, and restore/apply claims. Feature tests prove no customer output, no restore action, no new route/dashboard, and no tenant_id.

Functional Requirements (mandatory)

  • FR-424-001: The implementation MUST use existing Coverage v2 source contract, capture, resource/evidence, identity, redaction, read-model, and Claim Guard boundaries.
  • FR-424-002: securityDefaults MUST remain the only resource type in scope.
  • FR-424-003: The resource type registry MUST either keep Security Defaults safely blocked or promote it only when source contract, capture, identity, normalize, compare, render, redaction, and Claim Guard tests pass.
  • FR-424-004: Any source contract MUST be explicit in the repo graph contract registry and routed through GraphClientInterface via existing provider gateway/capture paths.
  • FR-424-005: Missing contract, unsupported source, missing permission, beta-only source, or failed capture MUST not create fake raw payloads, normalized payloads, content-backed evidence, comparable support, or renderable support.
  • FR-424-006: Captured evidence MUST persist raw payload, normalized payload, payload hash, source metadata, redacted permission context, operation_run_id, workspace_id, managed_environment_id, and same-scope provider_connection_id through existing tables.
  • FR-424-007: Provider connection scope MUST be validated against the same workspace and managed environment as the resource/evidence and OperationRun.
  • FR-424-008: Security Defaults identity MUST use CanonicalIdentityResolver and MUST never treat display name alone as stable identity.
  • FR-424-009: Typed normalization MUST produce deterministic Security Defaults fields including resource type, enabled state, source identity, source class, source version/schema when known, capture timestamp context, and unsupported-field diagnostics.
  • FR-424-010: Volatile metadata such as OData context/etag and timestamp/request/correlation fields MUST be ignored or diagnostics-only for compare purposes.
  • FR-424-011: Compare output MUST classify added, removed, changed, unchanged, ignored volatile, unsupported field, and redacted cases.
  • FR-424-012: Enabled-state changes MUST be classified as critical compare changes.
  • FR-424-013: Render output MUST be operator-safe and must not require raw payload display to answer enabled/disabled/unknown, evidence state, identity state, claim state, last captured, and blocker questions.
  • FR-424-014: Claim Guard MUST allow only scoped internal/operator statements for Security Defaults content-backed/comparable/renderable support.
  • FR-424-015: Claim Guard MUST block Security Defaults certified, restore-ready, customer-ready, full Entra, 100 percent Entra, M365 certified, report/review-pack, legal/regulatory, and restore/apply claims.
  • FR-424-016: No restore/apply action, restore claim, customer output, report, Review Pack inclusion, export, dashboard, or new route/navigation may be introduced.
  • FR-424-017: No tenant_id may be introduced as Coverage v2 ownership truth, compatibility alias, dual-write target, fallback reader, or parallel scope key.
  • FR-424-018: Runtime render/compare/readiness paths MUST perform no Graph, TCM, HTTP, Microsoft docs, or provider calls.
  • FR-424-019: Existing Coverage v2 rendered output MAY show Security Defaults summary on the internal/operator surface; any rendered change requires focused browser proof and Human Product Sanity.
  • FR-424-020: Any supported-scope entry or resolver behavior added for Security Defaults MUST be internal/operator-only and MUST NOT use forbidden scope names such as entra_certified, entra_full_coverage, entra_restore_ready, or m365_certified.
  • FR-424-021: Implementation close-out MUST record source contract result, evidence/capture matrix, identity strategy, supported-scope posture, normalizer/compare/render matrices, Claim Guard proof, redaction proof, no restore/certification/customer proof, no tenant_id, no mini-platform, Product Surface result, tests/browser/no-browser, deployment impact, and deferred work.

Non-Functional Requirements

  • NFR-424-001: Tests and runtime code MUST use fake provider payloads and must not require live Graph, TCM, Microsoft documentation, or network access.
  • NFR-424-002: The implementation MUST preserve existing workspace, managed-environment, provider-connection, RBAC, OperationRun, and redaction contracts.
  • NFR-424-003: Any new Graph contract or registry default MUST be covered by unit/feature tests so support cannot silently drift.
  • NFR-424-004: The implementation MUST remain small enough for one bounded implementation loop and must stop if a singleton capture framework, broad Entra platform, migration, or new UI surface becomes necessary.

Data / Truth Source Requirements

  • Execution truth: Existing OperationRun for tenant-configuration capture.
  • Artifact/evidence truth: Existing TenantConfigurationResource and TenantConfigurationResourceEvidence rows.
  • Source truth: Microsoft Graph through explicit repo graph contract and GraphClientInterface, or safe blocked state if no contract is approved.
  • Claim truth: Existing ClaimGuard output, not UI wording alone.
  • Display truth: Derived render summary from redacted normalized evidence, not raw payload display.

Out Of Scope

  • Entra certification or certified denominator activation.
  • Restore/apply, preview restore, assisted restore, or restore readiness.
  • Customer-facing Entra claims, reports, Review Pack output, PDF/export/download output.
  • Full Entra, full M365, Application, Service Principal, Role Definition, Administrative Unit, Authentication Methods, Identity Protection, Authorization Policy, Cross-Tenant Access, Access Review, or PIM support.
  • New Entra dashboard, route, navigation entry, mini-platform, table family, persisted compare table, or broad source framework.
  • Live Microsoft docs fetch, direct HTTP client, Graph SDK bypass, endpoint guessing from resource type name.

Acceptance Criteria

  • AC-424-001: Security Defaults has either a valid source contract and content-backed evidence path or a safe blocked missing-contract/unsupported state with no fake evidence.
  • AC-424-002: Captured Security Defaults evidence stores raw payload, normalized payload, payload hash, source metadata, redacted permission context, OperationRun link, and same-scope ownership fields through existing tables.
  • AC-424-003: Canonical identity resolution is used and unsafe identity states block or limit claims.
  • AC-424-004: Deterministic compare detects enabled-state changes as critical and ignores volatile-only changes.
  • AC-424-005: Operator-safe render summary answers enabled/disabled/unknown, content-backed, comparable, renderable, blocker, and last captured questions without raw payload display.
  • AC-424-006: Claim Guard blocks certification, restore, customer-ready, report/review-pack, full Entra, 100 percent, broad M365, and legal/regulatory claims.
  • AC-424-007: RBAC and scope tests prove 404 for non-member/wrong scope, 403 for established member without capability, readonly cannot start capture, and provider connections are same-scope.
  • AC-424-008: No tenant_id, new route/navigation/dashboard, restore action, customer output, or Security Defaults mini-platform is introduced.
  • AC-424-009: Browser proof and Human Product Sanity are recorded if rendered output changes; otherwise exact no-rendered-change proof is recorded.

Success Criteria

  • Security Defaults is eligible for later certified Entra denominator work because it is content-backed, comparable, renderable, and claim-limited internally.
  • Later Entra certification work can depend on real Security Defaults evidence instead of a registry-only placeholder.
  • The Coverage v2 path remains conservative: blocked means blocked, and no customer/restore/certification claims are activated.

Risks

Risk Severity Mitigation
Source contract cannot capture singleton payload through existing list path High Prove through focused tests; add only bounded singleton handling inside existing source/capture path or leave blocked
Security Defaults support is mistaken for certification High Claim Guard, wording restrictions, Product Surface proof, implementation report
Beta-only or unsupported source is promoted High Source-class tests, beta guard, certified-claim block
Raw payload or permission context leaks High Redaction tests, render summary tests, browser proof if rendered
Broad Entra scope creeps in Medium Explicit non-goals, stop conditions, tasks limited to securityDefaults

Assumptions

  • Existing Coverage v2 tables can represent Security Defaults evidence without migration.
  • ResourceTypeRegistry::syncDefaults() is expected to be the canonical runtime default-sync path; implementation preflight found the existing fresh-install migration seed also lists securityDefaults, so this spec permits only that one-row seed alignment after real source support is proven. Any other migration-seed edit or new migration remains out of scope.
  • Existing capture OperationRun type is sufficient for remote/provider work.
  • Existing Entra comparable/renderable helper family can be extended or mirrored without a new registry/framework.
  • Current repo pre-production posture allows clean replacement of the registry-only Security Defaults row when support is proven.

Open Questions

None block preparation. Implementation preflight must verify whether the repo-approved source contract can capture the singleton Security Defaults payload safely. If not, the implementation must keep Security Defaults blocked and record the blocker instead of widening scope.

Follow-Up Spec Candidates

  • Entra Certified Core Compare Pack including Conditional Access and Security Defaults.
  • Customer-safe Entra reporting / Review Pack claim guard.
  • Entra restore/apply safety exploration.
  • Additional Entra resource packs for Applications, Service Principals, Role Definitions, Administrative Units, authentication methods, and related identity governance domains.