Skip to content

Harden deployment identity, emergency access, evidence, and Graph boundaries - #8

Merged
Cj-Scott merged 2 commits into
mainfrom
cj-scott-deployment-safeguard-remediation
Sep 28, 2026
Merged

Cj-Scott merged 2 commits into
mainfrom
cj-scott-deployment-safeguard-remediation

Conversation

@Cj-Scott

@Cj-Scott Cj-Scott commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Implements the five confirmed deployment-safeguard remediation groups identified after PR #7, the independent follow-up finding that editable emergency-access evidence could substitute unverified principals, and the subsequently confirmed inherited standalone Conditional Access verification gap. Based on merged PR #7 at 24ee35c08cb0847de5b563d4122164bc298e85ab.

All agreed, confirmed defects in this remediation scope are addressed, including the standalone follow-up in ee2ea452ea6780d2ef963e15596df5c20cca8138 (a new commit, not an amendment). This is not a claim that every repository finding is a defect, that all repository bugs are fixed, or that the deployment is certified for production. No tenant authentication, deployment, live token-forwarding test, or pilot validation was performed. Release readiness remains blocked pending approved pilot validation and maintainer review.

Behavior changes

Area Fix and operator-visible effect Review source
Defender value comparison Restore the ordered dictionary initializer removed by the final PR #7 string fix. Preserve scalar string behavior; object, nested, dictionary, array and null comparisons no longer hit the null-index regression. Scalar-string discussion
Entra emergency-account creation Opt-in creation makes an account without granting privileges, then stops before CA writes. Operators must configure/test credentials and permanent tenant-wide Global Administrator recovery, configure the object ID, and rerun. A pre-existing proposed UPN is not silently adopted or duplicated. Previous diagnostic evidence is invalidated. Creation handoff
Entra emergency authorization The module returns exactly one structured in-memory result with current run ID, Boolean verification state and copied typed user/group arrays. The orchestrator validates cardinality, shape, types, run and principal-set consistency, then copies only those IDs into CA context. JSON is diagnostic only and is never read back to authorize exclusions. Missing/malformed results stop; skipped/unverified emergency access withholds CA writes. Independent follow-up reproduction: verify A, substitute JSON IDs to B while retaining markers, then observe CA requests excluding B. Regression tests now require A, never B.
Standalone CA write boundary Fixed in follow-up. Shared read-only verification now runs before each actual POST and adoption PATCH: verify actual Graph account and tenant against intended execution, read the organization ID, then verify the exact supplied users/groups, enabled recovery accounts/members and permanent tenant-wide Global Administrator role. Construct/serialize write bodies only afterward from copied verified IDs. Preserve unrelated template/customer exclusions and existing adoption state. Standalone actual writes now require the intended Context.TenantId GUID and Context.TenantAdminUpn. Assessment, WhatIf, both blocker lists, Security Defaults and manual migration remain supported; no verification flag bypass, account creation, automatic role grant or extra scope was added. Independently reproduced against the inherited module at 56f9844: arbitrary nonempty exclusions reached mocked default/enabled POST and enabled-policy adoption PATCH without directory/role reads. This was already present on main, not introduced by the in-memory handoff.
Entra/Intune operator identity Verify actual Get-MgContext.Account after fresh connection and before successful connection evidence/setup. Reject missing/wrong accounts; retain case-insensitive correct accounts, valid cached sessions, tenant checks and GDAP targeting. Disconnect invalid contexts without masking the identity failure. No added scopes. Entra, Intune
Defender evidence finalization Attempt JSON and HTML independently, surface redacted export warnings, preserve the original deployment error, and guarantee run-log cleanup even with WarningPreference=Stop. Missing reports remain missing evidence, not proof of successful deployment. Finalization
Intune API bases and paging Validate both stable and beta bases before authentication; reuse the validator at relevant dispatch surfaces. Allow supported Graph cloud hosts, HTTPS/default 443 and /v1.0 or /beta; reject unapproved hosts, nondefault ports, userinfo, fragments, queries/additional or ambiguous base components. Collection paging requires the same authority and exact collection path, rejects malformed links/cycles before SDK dispatch, and retains legitimate paging queries/opaque IDs. Compliance/enrollment readers share the same boundary. App deployment, app protection, beta base, CA paging

Report-only defaults, ShouldProcess/WhatIf, approval and recovery gates, documented role/guest/application targeting, exact readback, unmanaged collision guards, and manual ReviewExistingOnly migration are preserved. There is no automatic privilege grant or phishing-resistant policy adoption. File substitution is closed; arbitrary code compromise inside the PowerShell process is not addressed by an in-memory contract. Fresh directory verification and a subsequent CA write are not an atomic transaction against concurrent directory/session changes. A later-policy failure does not roll back earlier successful writes.

The standalone finding is a MEDIUM operational verification risk with potentially high enforcement/lockout impact, depending on policy state and scope—not demonstrated privilege escalation. In particular, report-only configuration does not neutralize adoption of an already enabled policy because adoption preserves its state. The reproduction used mocked SDK requests; acceptance of fake IDs by the live API was not proven.

Validation performed

Windows, PowerShell 7.6.6. All regression execution used synthetic SDK responses and invented identities, without tenant authentication/network calls. Fixtures and logs were retained outside the repository under C:\temp\deployment-safeguard-remediation. All listed suites were rerun for this follow-up; the final orchestrator run completed successfully before committing/pushing.

Command Result
pwsh -NoProfile -File .\scripts\verify.ps1 Passed: 66 product scripts parsed, 8 configurations validated
pwsh -NoProfile -File .\scripts\Test-IdentityReviewFixes.ps1 Passed: 196 assertions; fixture now supplies actual synthetic session/organization/principal/role responses, not trusted verification flags
pwsh -NoProfile -File .\scripts\Test-IntuneReviewFixes.ps1 Passed: 87 scenarios
pwsh -NoProfile -File .\scripts\Test-DefenderConnectionGuards.ps1 Passed: 16 scenarios
pwsh -NoProfile -File .\scripts\Test-DefenderComparableValues.ps1 Passed: 16 assertions
pwsh -NoProfile -File .\scripts\Test-DeploymentSafeguards.ps1 Passed: 140 scenarios, including orchestrator in-memory handoff and valid-marker JSON principal substitution
pwsh -NoProfile -File .\scripts\Test-EntraStandaloneWriteGuards.ps1 Passed: 96 actual standalone-module scenarios, covering both POST and enabled-policy adoption PATCH
git diff --check and staged diff check Passed
Relative Markdown links 88 links checked across 15 changed Markdown files; no missing targets
Maintainer quality gate, -BaseRef origin/main 36 changed files: 0 errors / 17 warnings
Same gate with -AllFiles 175 files: 6 errors / 47 warnings, whole-repository decision remains Blocked

The standalone suite asserts actual SDK write-request counts, fresh context/organization/principal/role reads per write, user/group response consistency (hashtable and PSCustomObject), permanent direct/group-mediated recovery, malformed/missing/wrong identity and tenant, unreadable directory/roles, disabled principals/members, temporary/expiring/scoped roles, fabricated markers, copied-array isolation, configured enabled creation, enabled adoption with default report-only configuration, retained customer exclusions, and revocation between writes. Invalid verification yields zero POST/PATCH; revocation after a successful first write blocks the second. WhatIf, both blocker lists, Security Defaults and empty-exclusion handling remain covered.

The broader safeguards suite executes actual modules/orchestrators. Coverage includes created/disabled/roleless/unreadable emergency accounts, skipped verification, rerun duplicate prevention, valid apply/WhatIf, post-verification JSON user/group replacement/addition/removal and stale/malformed markers, 14 malformed in-memory result contracts, copied arrays, fresh/cached identity and tenant mismatch, independent report-failure combinations, and valid/invalid paging before mocked dispatch. URI tests do not demonstrate live bearer-token forwarding or exfiltration.

Changed-scope gate warning disposition: 13 generic Add-RunLogEntry spelling checks are covered by product-specific loggers or pure helpers whose callers own evidence; 3 product-navigation warnings do not apply because no product inventory/navigation/common prerequisite changed; 1 missing pilot-evidence warning is a real outstanding release gate. These explanations do not suppress gate output or waive whole-repository findings. Compared with the initial PR version, the two additional scoped logger warnings come from the newly touched shared directory helper and public CA module; the whole-repository baseline findings remain unchanged.

Findings not changed / deferred

This table intentionally distinguishes rejected claims, behavior already guarded/fixed, qualified impact claims, and genuinely pending validation. Review links refer to the original discussions, not an assertion that every original comment was correct. The newly confirmed standalone defect is fixed, as recorded above; no newly confirmed code defect in the agreed scope is being deferred.

Finding / original discussion Disposition Reason / evidence Remaining owner / action
Organization read scopes: Defender, follow-up, Intune False positive for the selected delegated fields Graph documentation permits delegated User.Read for id, displayName, verifiedDomains. No Organization.Read.All expansion is needed for these reads. Maintainer: retain least privilege; reassess if requested fields/auth mode change.
OrderedHashtable compatibility False positive Reproduced with PowerShell 7.6.6: ConvertFrom-Json -AsHashtable returns OrderedHashtable, whose base is Hashtable; -is [hashtable] is true. No type-check rewrite.
Update-MgDeviceManagement -Settings False positive The documented cmdlet syntax includes -Settings <IMicrosoftGraphDeviceManagementSettings>. Preserve valid invocation; tenant/service support still belongs in the pilot.
Unmanaged app-protection collision Already guarded in the original revision Original import 6fbfdc7 already counts UnmanagedSameNamePolicyCount and blocks create-only deployment rather than adopting/overwriting the object. Preserve existing guard; no duplicate guard added.
Existing phishing-resistant policy adoption Already guarded/manual migration Original revision already takes the ReviewExistingOnly branch for existing policies and requires human review rather than PATCH/adoption, including with AdoptExisting. Operator owns manual review/migration; no automatic adoption added.
Admin targeting: first finding, follow-up Already fixed in PR #7; original intersection rationale incorrect Preserve the merged role-targeting correction. User/group/role includes use union semantics; this is not an outstanding administrator-exclusion defect. Maintain documented role scope; validate impact in pilot.
Singular enrollment discriminator Valid API type; inventory mismatch already fixed in PR #7 deviceEnrollmentPlatformRestrictionConfiguration is a valid singular beta resource. Preserve discriminator and existing inventory fix; beta availability requires pilot validation.
Defender verdict precedence, MFA OR fallback, Azure management targeting, session controls Already fixed in PR #7 Existing implementations preserved; affected identity/Defender regressions pass. Maintainer: retain these fixes during review.
Exclusion-only assignment, compliance readback, enrollment readback, guest scope Already fixed in PR #7 Preserve unknown/exclusion-only assignment handling, exact readback and documented guest scope; existing Intune/identity regressions pass. No duplicate rewrite; operator validates supported paths in pilot.
Defender GDAP targeting, account-bound preflight Already fixed in PR #7 Preserve target-tenant and account binding; Defender connection regressions pass. Retain guards and perform approved authentication pilot.
Auth impact: discussion, qualification Confirmed binding/evidence-integrity issue addressed; impact qualified Fresh operator mismatch is now rejected. A mismatch does not itself prove privilege escalation; this PR makes no unsupported escalation or live token-exfiltration claim. Reviewer: assess the demonstrated boundary, not speculative impact.
Standalone recovery-check limits after the inherited gap fix Boundary defect fixed; concurrency/runtime limits remain explicit Revalidation before POST/PATCH does not make directory reads and CA writes atomic, protect against arbitrary in-process compromise, or prove live API acceptance of fabricated IDs. Report-only creation and existing enabled-policy adoption have different impact. Operator/identity owner: maintain tested recovery and change control; reviewer: do not interpret synthetic checks as a lockout guarantee or privilege-escalation proof.
Approved tenant pilot / live API, readback and recovery evidence Deferred release blocker Parser/mocks cannot establish real service permissions, cloud/resource availability, recovery readiness or rollback behavior. No pilot approval was supplied. Tenant deployment/identity owner + release approver: approve targeted/full-orchestrator WhatIf, then separately approved apply/readback/recovery validation; retain private evidence before release.
Whole-repository quality gate: 6 errors / 47 warnings Pre-existing baseline findings; not suppressed All six lexical .ShouldProcess errors are in untouched read-only/guided modules: Defender Setup-DefenderForCloudApps, Setup-DefenderPreflight, Setup-MdeAdvanced; Intune Setup-EnrollmentPrerequisites, Setup-EnterpriseStateRoaming, Setup-IntunePreflight. The 47 warnings use the generic evidence-logger heuristic. These are not automatically proven unsafe writes, but the baseline gate remains blocked. Maintainers: review each baseline finding against actual behavior, fix any genuine gap or formally disposition non-applicable heuristics. This scoped change neither repairs unrelated modules nor waives the gate.

Documentation and review boundaries

Updated all three affected product READMEs, Entra break-glass/operator/scenario/evidence guides, Intune configuration/evidence guides, Defender evidence/troubleshooting guides, changelog and regression commands. The standalone follow-up also updates module help, the operator's intended-tenant prerequisite, write-boundary failure recovery, and shared verification documentation. A separate deployment-safeguard review in docs/Responsible-AI-Review.md records Secure by Design/Default/Operations controls, AI-assisted engineering accountability, synthetic evaluation limits and release owners. No rich HTML companions exist for these affected guides. No new AI runtime/model behavior, secrets, customer evidence or credentials are added.

<!-- BEGIN pr-telemetry -->
assistance: agentic-cli
type: bug
agent-tool: copilot-cli
agent-model: gpt-6-astra
work-item: AB#n/a
<!-- END pr-telemetry -->

…ndaries

Return verified emergency exclusions in memory rather than trusting diagnostic JSON. Add synthetic module/orchestrator regressions and operator recovery guidance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Cj-Scott
Cj-Scott requested review from a team and a lite review from Copilot September 28, 2026 18:15
@Cj-Scott Cj-Scott added agentic-cli Work primarily authored by a terminal AI agent bug Something isn't working labels Sep 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

A critical standalone Conditional Access path can bypass verified emergency-access authorization, and release validation remains outstanding.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Hardens Entra emergency access, Intune Graph boundaries, Defender evidence handling, and offline regression coverage.

Changes:

  • Enforces verified in-memory emergency-access authorization.
  • Validates Graph endpoints, paging links, and operator identities.
  • Improves Defender comparisons, evidence exports, and cleanup.

Review identified a critical standalone Conditional Access bypass, a malformed regression-test fault injection, and contradictory operator documentation.

File Reviewed changes
scripts/​Test-DeploymentSafeguards.ps1 Adds safeguard regression scenarios; one malformed-result test requires correction.
scripts/​Test-DefenderComparableValues.ps1 Tests Defender value comparisons.
Products/​Intune/​README.md Documents identity and endpoint safeguards.
Products/​Intune/​Modules/​Setup-EnrollmentRestrictions.ps1 Applies shared paging validation.
Products/​Intune/​Modules/​Setup-DeviceConditionalAccess.ps1 Validates CA paging and endpoint construction.
Products/​Intune/​Modules/​Setup-DeviceCompliancePolicies.ps1 Applies compliance paging validation.
Products/​Intune/​Modules/​Setup-AppProtectionPolicies.ps1 Validates Graph bases and paging.
Products/​Intune/​Modules/​Setup-AppDeployment.ps1 Validates app Graph access and paging.
Products/​Intune/​Modules/​IntuneGraphClient.ps1 Adds shared Graph URI validation.
Products/​Intune/​Modules/​Connect-IntuneServices.ps1 Verifies the actual signed-in account.
Products/​Intune/​docs/​Evidence-Troubleshooting.md Documents identity and endpoint failures.
Products/​Intune/​docs/​Configuration-Reference.md Defines Graph endpoint contracts.
Products/​Intune/​Deploy-IntuneBestPractice.ps1 Validates Graph configuration before authentication.
Products/​Entra/​README.md Documents emergency-access and identity behavior.
Products/​Entra/​Modules/​Setup-EmergencyAccess.ps1 Implements safe account creation and verification results.
Products/​Entra/​Modules/​Connect-EntraServices.ps1 Verifies the actual signed-in account.
Products/​Entra/​docs/​Scenarios.md Updates emergency-access workflows.
Products/​Entra/​docs/​Operator-Guide.md Documents operator safeguards; report wording remains contradictory.
Products/​Entra/​docs/​Evidence-Troubleshooting.md Documents evidence boundaries.
Products/​Entra/​docs/​Break-Glass-Guide.md Documents manual account handoff.
Products/​Entra/​Deploy-EntraBestPractice.ps1 Gates orchestrated CA deployment, but standalone CA invocation remains unprotected.
Products/​Entra/​Config/​EntraConfig.psd1 Clarifies account-creation configuration.
Products/​Defender/​README.md Documents evidence export behavior.
Products/​Defender/​Modules/​DefenderStateManagement.ps1 Restores ordered comparable-value handling.
Products/​Defender/​Modules/​DefenderRunLog.ps1 Surfaces JSON export warnings.
Products/​Defender/​docs/​troubleshooting.md Documents report-export troubleshooting.
Products/​Defender/​docs/​evidence.md Documents evidence failure semantics.
Products/​Defender/​Deploy-DefenderBestPractice.ps1 Preserves errors and guarantees log cleanup.
docs/​Responsible-AI-Review.md Records safeguard scope and residual risks.
docs/​conventions.md Adds offline validation commands.
CHANGELOG.md Records remediation changes.
AGENTS.md Updates responsible-review guidance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

…daries

Share read-only principal verification and validate the actual operator and intended tenant before each create or adoption write. Preserve assessment, WhatIf, customer exclusions, and existing enforcement state; add 96 offline standalone boundary scenarios.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 28, 2026 19:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Unresolved moderate test-suite issues remain, and approved live pilot validation is still outstanding.

Review effort: Lite
Findings: None

Resolved since last review (1)

@Cj-Scott
Cj-Scott merged commit d21f235 into main Sep 28, 2026
2 checks passed
@Cj-Scott
Cj-Scott deleted the cj-scott-deployment-safeguard-remediation branch September 28, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-cli Work primarily authored by a terminal AI agent bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants