Skip to content

Add CIS.M365.5.1.4.6: Ensure users are restricted from recovering BitLocker keys#1950

Merged
merill merged 4 commits into
maester365:mainfrom
BakkerJan:feature/CIS-5.1.4.6-bitlocker-key-recovery-restricted
Jul 20, 2026
Merged

Add CIS.M365.5.1.4.6: Ensure users are restricted from recovering BitLocker keys#1950
merill merged 4 commits into
maester365:mainfrom
BakkerJan:feature/CIS-5.1.4.6-bitlocker-key-recovery-restricted

Conversation

@BakkerJan

@BakkerJan BakkerJan commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds Test-MtCisEnsureBitLockerKeyRecoveryRestricted, which checks that authorizationPolicy.defaultUserRolePermissions.allowedToReadBitlockerKeysForOwnedDevice is false, so non-admin users can't self-service recover the BitLocker recovery key(s) for devices they own via the My Account portal or the Entra admin center.
  • Maps to CIS Microsoft 365 Foundations Benchmark v6.0.1 control 5.1.4.6 "Ensure users are restricted from recovering BitLocker keys" (L2, applicable to both E3 and E5).
  • Added under powershell/public/cis/ and tests/cis/, following the existing Test-MtCisEnsureUserConsentToAppsDisallowed pattern (same policies/authorizationPolicy resource).

Background: https://janbakker.tech/block-users-from-viewing-their-bitlocker-keys/

Test plan

  • Invoke-ScriptAnalyzer on the new file — no findings
  • ./build/Build-LocalMaester.ps1 — builds and imports cleanly, new function exported
  • ./powershell/tests/pester.ps1 — all 6293 QA tests pass
  • Maintainer review of CIS control mapping and function naming

Summary by CodeRabbit

  • New Features

    • Added a CIS Microsoft 365 Benchmark 5.1.4.6 check to verify that non-admin users are restricted from recovering BitLocker keys for devices they own.
    • The check reports pass, fail, skipped, and error outcomes with supporting details.
    • Added remediation guidance, including Microsoft Entra admin center and Microsoft Graph instructions.
  • Tests

    • Added coverage to validate the new BitLocker key recovery restriction check.

…keys

Adds a new CIS Microsoft 365 Foundations Benchmark v6.0.1 test
(control 5.1.4.6, L2, E3/E5) that checks the tenant-level
authorizationPolicy.defaultUserRolePermissions.allowedToReadBitlockerKeysForOwnedDevice
setting is false, so non-admin users can't self-service recover the
BitLocker key(s) for devices they own.

See https://janbakker.tech/block-users-from-viewing-their-bitlocker-keys/
@BakkerJan
BakkerJan requested a review from a team as a code owner July 17, 2026 07:44
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a CIS 5.1.4.6 test that verifies non-admin users cannot recover BitLocker keys for owned devices, documents remediation, exports the cmdlet, and adds Pester coverage.

Changes

BitLocker recovery restriction control

Layer / File(s) Summary
Authorization policy check
powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.ps1, powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md
The new cmdlet evaluates the Microsoft Graph authorization policy, records pass/fail or skipped results, and includes CIS remediation guidance and a Graph PowerShell example.
Module integration and validation
powershell/Maester.psd1, tests/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.Tests.ps1
The cmdlet is added to module exports, with Pester coverage asserting a passing result when BitLocker key recovery is restricted.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TestCmdlet
  participant MicrosoftGraph
  participant TestResult
  TestCmdlet->>MicrosoftGraph: Read authorization policy
  MicrosoftGraph-->>TestCmdlet: Return BitLocker recovery setting
  TestCmdlet->>TestResult: Add pass, fail, skipped, or error detail
Loading

Suggested labels: maester-test

Suggested reviewers: merill

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description has a useful summary and test plan, but it misses required template sections like Closes #, checklist items, and Additional Information. Reformat the PR description to match the template: add a Description section with Closes #, complete the Checks checklist, and include Additional Information.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately states the main change: adding a CIS check for BitLocker key recovery restrictions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
powershell/public/cis/Test-MtCisEnsureBitlockerKeyRecoveryRestricted.md (1)

22-22: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Specify a language for the fenced code block.

To improve syntax highlighting and resolve the markdownlint warning, specify powershell as the language for this code block.

♻️ Proposed fix
-```
+```powershell
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@powershell/public/cis/Test-MtCisEnsureBitlockerKeyRecoveryRestricted.md` at
line 22, Specify powershell as the language identifier on the fenced code block
in Test-MtCisEnsureBitlockerKeyRecoveryRestricted documentation, changing the
opening fence to use the powershell annotation while leaving the block content
unchanged.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@powershell/public/cis/Test-MtCisEnsureBitlockerKeyRecoveryRestricted.md`:
- Line 22: Specify powershell as the language identifier on the fenced code
block in Test-MtCisEnsureBitlockerKeyRecoveryRestricted documentation, changing
the opening fence to use the powershell annotation while leaving the block
content unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 899b336c-9ac2-4131-ac35-1a57e4623632

📥 Commits

Reviewing files that changed from the base of the PR and between 934252a and 1ad780e.

📒 Files selected for processing (4)
  • powershell/Maester.psd1
  • powershell/public/cis/Test-MtCisEnsureBitlockerKeyRecoveryRestricted.md
  • powershell/public/cis/Test-MtCisEnsureBitlockerKeyRecoveryRestricted.ps1
  • tests/cis/Test-MtCisEnsureBitlockerKeyRecoveryRestricted.Tests.ps1

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.Tests.ps1 (1)

4-8: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not silently pass when the check returns $null.

Test-MtCisEnsureBitLockerKeyRecoveryRestricted returns $null for disconnected and error paths, but this test then performs no assertion. That can produce a green test run without evaluating the CIS control. Handle $null explicitly as a real Pester skip using the repository’s established mechanism, then assert $true for non-skipped executions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.Tests.ps1` around
lines 4 - 8, Update the test around
Test-MtCisEnsureBitLockerKeyRecoveryRestricted to handle a $null result
explicitly using the repository’s established Pester skip mechanism. Only skip
for the disconnected or error-path null outcome; otherwise assert that the
result is $true.
powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md (1)

22-29: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Document the required administrator role.

Policy.ReadWrite.Authorization alone is insufficient; the signed-in user must also have a supported Entra role, with Privileged Role Administrator being the least-privileged documented role. (learn.microsoft.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md`
around lines 22 - 29, Update the documentation around Connect-MgGraph in
Test-MtCisEnsureBitLockerKeyRecoveryRestricted to state that, in addition to
Policy.ReadWrite.Authorization, the signed-in administrator must hold a
supported Entra role; identify Privileged Role Administrator as the
least-privileged supported role.
🧹 Nitpick comments (1)
powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md (1)

22-29: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Serialize the remediation body as JSON.

The Graph PATCH endpoint requires application/json; make the documentation explicit rather than relying on implicit hashtable serialization. (learn.microsoft.com)

Proposed documentation update
-Invoke-MgGraphRequest -Method PATCH -Uri "https://graph.microsoft.com/v1.0/policies/authorizationPolicy" -Body $params
+$body = $params | ConvertTo-Json -Depth 3
+Invoke-MgGraphRequest -Method PATCH -Uri "https://graph.microsoft.com/v1.0/policies/authorizationPolicy" -Body $body -ContentType "application/json"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md`
around lines 22 - 29, Update the remediation example around $params and
Invoke-MgGraphRequest to explicitly serialize the hashtable body as JSON before
issuing the PATCH request, while preserving the existing authorizationPolicy
values and endpoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md`:
- Around line 22-29: Update the documentation around Connect-MgGraph in
Test-MtCisEnsureBitLockerKeyRecoveryRestricted to state that, in addition to
Policy.ReadWrite.Authorization, the signed-in administrator must hold a
supported Entra role; identify Privileged Role Administrator as the
least-privileged supported role.

In `@tests/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.Tests.ps1`:
- Around line 4-8: Update the test around
Test-MtCisEnsureBitLockerKeyRecoveryRestricted to handle a $null result
explicitly using the repository’s established Pester skip mechanism. Only skip
for the disconnected or error-path null outcome; otherwise assert that the
result is $true.

---

Nitpick comments:
In `@powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md`:
- Around line 22-29: Update the remediation example around $params and
Invoke-MgGraphRequest to explicitly serialize the hashtable body as JSON before
issuing the PATCH request, while preserving the existing authorizationPolicy
values and endpoint.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 194290b5-09d8-4174-b9dd-88275991efb4

📥 Commits

Reviewing files that changed from the base of the PR and between 692f6a8 and f0502c4.

📒 Files selected for processing (4)
  • powershell/Maester.psd1
  • powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.md
  • powershell/public/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.ps1
  • tests/cis/Test-MtCisEnsureBitLockerKeyRecoveryRestricted.Tests.ps1
🚧 Files skipped from review as they are similar to previous changes (1)
  • powershell/Maester.psd1

@merill merill 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.

This looks good. Thanks @BakkerJan !!

@merill
merill merged commit 4da2e8b into maester365:main Jul 20, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants