Skip to main content

Collection Phases

Data collection executes in four sequential phases. Phase order is fixed. Management group structure must be resolved before subscriptions can be enumerated, and subscriptions must be enumerated before per-subscription calls can execute in parallel.

PhaseNameExecutionEstimated API calls
1Tenant StructureSequential5–20
2Resource Graph (B1 Items)Batched10–20 batches
3REST API (B2 Foundation + Sentinel)Async parallel100–350
4Microsoft Graph (Entra ID)Sequential4–6

Phase 1 — Tenant Structure

Establishes the complete tenant scope for all subsequent phases. Must complete before any other phase begins.

GET /providers/Microsoft.Management/managementGroups
GET /providers/Microsoft.Management/managementGroups/{id}/descendants [per MG]
GET /subscriptions
GET /subscriptions/{id}/locations [per subscription]
GET /subscriptions/{id}/resourceGroups [per subscription]
GET /subscriptions/{id}/tagNames [per subscription]

Phase 2 — Resource Graph Queries (B1 Items)

Executes all graph queries extracted from the CYC checklist inventory. Each query returns a list of Azure resource IDs with a compliant boolean per resource. Results are aggregated to item-level compliance status.

ChecklistB1 itemsHighest graph coveragePrimary resource types
Azure Landing Zone (ALZ)49Network — 34%VNet, Firewall, ExpressRoute, NSG
AKS23Network — 37%Managed clusters, node pools
App Delivery Networking10Network — 25%App Gateway, Front Door, Load Balancer
SAP20Mgmt Groups — 62%VMs, storage accounts, availability zones
AVD / Cost / Multitenancy0All items are B2 or B3

Item-level aggregation rules:

Conditionitem_status
All resources compliantcompliant
One or more non-compliantnon_compliant
No resources returnednot_applicable
Query execution errorerror — logged to collection_errors

Phase 3 — REST API Collection (B2 Foundation)

Collects structured environment data required by the Assessment Engine to evaluate B2 checklist items. Calls execute asynchronously per subscription using Python asyncio.

Core REST API Domains

DomainAPI callsScope
Policy assignmentspolicyAssignments, policyDefinitionsPer subscription + MG
RBACroleAssignments, roleDefinitionsPer subscription
Management groupsmanagementGroups, descendantsTenant root
Subscriptionssubscriptions, locations, resourceGroups, tagNamesPer subscription
Defender for CloudsecureScores, assessments, pricings, autoProvisioningSettingsPer subscription
Monitoring / InsightsdiagnosticSettings, activityLogAlerts, scheduledQueryRulesPer subscription
Log AnalyticsworkspacesPer subscription
Cost ManagementCostManagement/query, budgets, reservationRecommendationsPer subscription

Conditional Sentinel Block

If the client indicated Microsoft Sentinel is deployed in the intake questionnaire and the Sentinel Reader role was granted during OAuth consent, a conditional block executes after core REST API calls.

Detection step — always executed:

GET /subscriptions/{id}/providers/Microsoft.OperationsManagement/solutions

If Sentinel confirmed deployed:

GET /subscriptions/{id}/providers/Microsoft.SecurityInsights/alertRules
GET /subscriptions/{id}/providers/Microsoft.SecurityInsights/dataConnectors
GET /subscriptions/{id}/providers/Microsoft.SecurityInsights/automationRules
GET /subscriptions/{id}/providers/Microsoft.SecurityInsights/incidents?$filter=status eq 'Active'&$top=100
Privacy note

The incidents call retrieves a count and severity distribution of open incidents only. Incident titles, descriptions, entities, and alert details are not collected. CYC assesses whether Sentinel is operationally active — not the content of client security events.

Phase 4 — Microsoft Graph (Entra ID)

Collects identity and access configuration using the Graph API endpoint. Required for evaluating ALZ Identity and Access Management checklist items.

GET /v1.0/identity/conditionalAccess/policies
GET /v1.0/directoryRoles
GET /v1.0/policies/authorizationPolicy
GET /v1.0/subscribedSkus