Files
macOS_IntuneManagement/Baselines/CISM365-v7.example.yaml.md
T
tomas.kracmar d3e0769799 release: v4.1.0 — restructure entry points, add CIS baselines, reporting tools and fzf hints
- Restructure launchers: Start-IntuneToolkit.ps1 moves to repo root;
  Start-HeadlessIntune.ps1 moves to Scripts/; TUI helper moves to Scripts/Private/
- Add AGENTS.md with project architecture, entry points, and security notes
- Add CIS M365 baseline assets (CISM365-v7, M365-CIS-Rapid) and reporting scripts
- Add Python reporting utilities (Export-SettingsReport, Export-AssignmentReport,
  Export-ObjectInventoryReport) and CA wizard helpers
- Update Deploy-IntuneBaseline.ps1 with Merge conflict resolution, ReportPath,
  and optimized group loading
- Update Initialize-IntuneAuth.ps1 with -RotateSecret and configurable secret expiry
- Update Extensions for Settings Catalog definition auto-export
- Update README with v4.1.0, new entry points and script catalog
- Bump VERSION to 4.1.0
- Harden .gitignore against .DS_Store, __pycache__, .venv-pdf/, local exports,
  Settings.json and IntuneManagement.log
2026-06-14 15:24:42 +02:00

238 lines
6.9 KiB
Markdown

# CIS M365 v7.0.0 YAML Baseline Format
This document describes the YAML schema for `CISM365-v7.example.yaml`, which extends the existing `OpenIntuneBaseline.example.yaml` format to cover **tenant-level** M365 configuration.
## Why This Format?
The existing Intune baseline YAML works great for device policies. For CIS M365 compliance, you need the same declarative approach but for:
- Entra ID settings (password policies, device quotas, consent)
- Conditional Access policies
- Defender for Office 365 policies
- Exchange Online transport rules
- SharePoint / OneDrive sharing
- Microsoft Teams policies
This YAML keeps the **same root structure** as the Intune baseline so you can optionally include Intune policies in the same manifest, or keep them separate.
## Root Structure
```yaml
baseline:
name: string
conflictResolution: Skip | Update | Error
whatIf: false
tenantMutation:
search: string # optional
replace: string # optional
prefix: string # optional (alternative to search/replace)
groups: [] # Cloud-only security groups (same as Intune baseline)
policies: [] # Intune policies (optional, same schema as Intune baseline)
tenantConfig: # NEW: M365 tenant-level configuration
adminCenter: {}
entraId: {}
conditionalAccess: {}
defender: {}
exchange: {}
sharePoint: {}
teams: {}
```
## tenantConfig Sections
### adminCenter
M365 Admin Center settings.
```yaml
adminCenter:
passwordExpiration: NeverExpire # NeverExpire | 90Days | 180Days
idleSessionTimeoutHours: 3
restrictUserOwnedApps: true
formsPhishingProtection: true
customerLockbox: true
restrictThirdPartyStorage: true
```
### entraId
Entra ID directory settings.
```yaml
entraId:
blockUserConsent: true
blockTenantCreation: true
restrictAdminCenterAccess: true
disableLinkedIn: true
maxDevicesPerUser: 5
gaLocalAdminDisabled: true
bannedPasswords:
- "Contoso"
- "Password"
```
### conditionalAccess
The most powerful section. Supports **automatic CA policy creation** with:
- **Global `reportOnly` switch** — all policies default to report-only
- **Automatic break-glass exclusion** — specify one group, it's excluded from every policy
- **Custom naming** via `tenantMutation`
- **Role name resolution** — use friendly names like "Global Administrator", script maps to template IDs
```yaml
conditionalAccess:
reportOnly: true # Global switch
breakGlassGroup: "CIS-BreakGlass" # Auto-excluded from all policies
policies:
- name: "Block-Legacy-Auth"
cisControl: "5.2.2.3"
description: "Block legacy authentication"
state: enabledForReportingButNotEnforced
conditions:
applications:
includeApplications: ["All"]
users:
includeUsers: ["All"]
excludeGroups: ["CIS-Pilot-Users"]
clientAppTypes: ["exchangeActiveSync", "other"]
grantControls:
builtInControls: ["block"]
operator: "OR"
```
**CA Policy Conditions Supported:**
| Condition | YAML Key | Example |
|-----------|----------|---------|
| Apps | `applications.includeApplications` | `["All"]` or `["Office365"]` |
| User actions | `applications.includeUserActions` | `["urn:user:registersecurityinfo"]` |
| Users | `users.includeUsers` | `["All"]` or specific UPNs |
| Groups | `users.includeGroups` / `excludeGroups` | `["CIS-Pilot-Users"]` — resolved by displayName |
| Roles | `users.includeRoles` / `excludeRoles` | `["Global Administrator"]` — friendly names mapped to template IDs |
| Client apps | `clientAppTypes` | `["exchangeActiveSync", "other"]` |
| Sign-in risk | `signInRiskLevels` | `["medium", "high"]` |
| Locations | `locations.includeLocations` | `["AllTrusted"]` or `["All"]` |
| Auth flows | `authenticationFlows.deviceCodeFlow` | `{ isEnabled: true }` |
**Grant Controls Supported:**
| Control | YAML Key |
|---------|----------|
| Block | `grantControls.builtInControls: ["block"]` |
| Require MFA | `grantControls.builtInControls: ["mfa"]` |
| Compliant device | `grantControls.builtInControls: ["compliantDevice", "domainJoinedDevice"]` |
| Phishing-resistant MFA | `grantControls.builtInControls: ["authenticationStrength"]` + `grantControls.authenticationStrength.id` |
**Session Controls Supported:**
```yaml
sessionControls:
signInFrequency:
value: 12
type: hours
isEnabled: true
persistentBrowser:
mode: never # never | always
isEnabled: true
```
### defender
Defender for Office 365 policies.
```yaml
defender:
safeLinks:
- name: "SafeLinks-Default"
cisControl: "2.1.1"
enabled: true
trackClicks: true
allowClickThrough: false
scanUrls: true
enableForInternalSenders: true
safeAttachments:
- name: "SafeAttachments-Default"
cisControl: "2.1.4"
enabled: true
action: Block
quarantineMessages: true
antiMalware:
- name: "AntiMalware-Default"
cisControl: "2.1.2"
enabled: true
enableInternalNotifications: true
fileTypes: ["ace", "exe", "jar", "vbs"]
```
### exchange
Exchange Online settings.
```yaml
exchange:
enableMailboxAuditOrgWide: true
blockExternalForwarding: true
enableExternalSenderBanner: true
externalEmailWarningRule: true
```
### sharePoint
SharePoint / OneDrive sharing settings.
```yaml
sharePoint:
adminUrl: "https://contoso-admin.sharepoint.com"
defaultSharingLinkType: Direct
sharePointExternalSharing: Disabled
oneDriveExternalSharing: Disabled
guestAccessExpirationDays: 30
denyCustomScripts: true
```
### teams
Microsoft Teams policies.
```yaml
teams:
allowAnonymousUsersToJoinMeeting: false
allowAnonymousUsersToStartMeeting: false
enableEmailIntegration: false
allowFederatedUsers: false
allowTeamsConsumer: false
```
## Using the Draft PDF
Since CIS does not publish XLS for draft benchmarks:
1. Open the PDF and work through each section
2. For **automated** controls, add them to the appropriate `tenantConfig` section with the `cisControl` field
3. For **manual** controls, skip them or add a comment
4. The `cisControl` field preserves traceability (e.g., `cisControl: "5.2.2.3"`)
## Deployment
```powershell
# Assess (read-only)
./Scripts/Deploy-CISM365Baseline.ps1 -BaselinePath ./Baselines/mytenant-cisv7.yaml
# Deploy (applies changes)
./Scripts/Deploy-CISM365Baseline.ps1 -BaselinePath ./Baselines/mytenant-cisv7.yaml -Mode Deploy -Apply -Verbose
# Deploy only specific workloads
./Scripts/Deploy-CISM365Baseline.ps1 -BaselinePath ./Baselines/mytenant-cisv7.yaml -Mode Deploy -Apply -Workloads ConditionalAccess,EntraID
```
## Safety Defaults
| Feature | Default | Why |
|---------|---------|-----|
| `Mode` | `Assess` | Must explicitly opt in to changes |
| `conditionalAccess.reportOnly` | `true` | All CA policies created in report-only mode |
| `breakGlassGroup` | Auto-excluded | Prevents lockout |
| `Apply` switch | Required for Deploy | Double-confirmation pattern |
| `-WhatIf` | Supported | Native PowerShell WhatIf |