Microsoft Defender for Cloud -- Findings Management Process
Overview
This document defines how the eshars team triages, tracks, and resolves Microsoft Defender for Cloud security recommendations across our Azure environment.
All findings are tracked in the Jira DEVOPS project under severity-based Epics. Severity tiers match Defender’s recommendation severity directly (High/Medium/Low).
Jira Epic Structure
| Epic | Key | Priority | SLA | Use For |
|---|---|---|---|---|
| Defender - High | DEVOPS-82 | High | 1 week | Matches Defender High severity recommendations |
| Defender - Medium | DEVOPS-83 | Medium | 2 weeks | Matches Defender Medium severity recommendations |
| Defender - Low | DEVOPS-84 | Low | 1-2 sprints | Matches Defender Low severity recommendations |
| Defender - Non-Issue | DEVOPS-85 | Lowest | Document & close | False positive, not applicable, compensating control exists |
| Defender - Won’t Do (Pending Approval) | DEVOPS-86 | Low | Awaiting approval | Team lead must approve before closing |
Note: Defender recommendations use 3 severity levels (High/Medium/Low). The “Critical” category shown in the Defender portal is a risk-based aggregation that considers attack paths, internet exposure, and resource context — it is NOT a per-recommendation severity. We capture risk-based status using labels (see below).
Label Taxonomy
Required Labels
| Label | When to Apply |
|---|---|
Defender | Every Defender-sourced finding (required) |
defender-high | Issue under DEVOPS-82 (High) |
defender-medium | Issue under DEVOPS-83 (Medium) |
defender-low | Issue under DEVOPS-84 (Low) |
defender-nonissue | Issue under DEVOPS-85 |
defender-wontdo | Issue under DEVOPS-86 |
Environment Labels
| Label | When to Apply |
|---|---|
env-prod | Finding affects at least one production resource |
env-nonprod | Finding affects at least one non-production resource |
Issues affecting both environments get both labels.
Classification rules:
- prod: resource name/group contains
prod,prodwest,tmhp,sftp,ssrs16-prod,rns-prod - non-prod: resource name/group contains
nonprod,dev,uat,qa,training,regression,test,poc,interview - ambiguous: flag for team lead confirmation, default to prod (safer)
Risk-Based Labels (Optional)
| Label | When to Apply |
|---|---|
risk-critical | Finding appears in Defender’s Critical risk-based view (portal) |
risk-high | Finding appears in Defender’s High risk-based view |
attack-path | Finding has associated attack path alerts |
These labels capture the Defender portal’s risk-based aggregation, which considers factors beyond recommendation severity (attack paths, internet exposure, lateral movement potential). Review and update these during monthly intake.
Jira Conventions
- Label (required):
Defender+ severity label + at least one env label - Priority: Must match the severity Epic (High/Medium/Low/Lowest)
- Epic Link (
customfield_10007): Must point to the matching severity Epic - Issue Type: Task (under the appropriate Epic)
Severity Assignment
Severity comes directly from Defender’s recommendation severity (High/Medium/Low). We no longer apply custom severity assessments.
- Pull the finding from
az security assessment-metadata listto get the recommendation severity - Assign to the matching Epic
- If severity is “Unknown” (e.g., MDVM secrets scanner findings), default to Medium
When to Override Defender Severity
Override only with team lead approval and documented justification:
- Upgrade: Finding has known active exploit or direct compliance impact
- Downgrade: Compensating control fully mitigates the risk (move to Non-Issue instead)
Intake: Pulling New Findings
Run these commands monthly (at minimum) to check for new Defender recommendations:
# Ensure correct subscriptionaz account set --subscription 9639039c-86c6-4859-b014-d28688863cd5
# Pull assessment metadata (contains severity)az security assessment-metadata list -o json > security/metadata-$(date +%Y%m%d).json
# Pull unhealthy assessments (contains affected resources)az security assessment list \ --query "[?status.code=='Unhealthy']" \ -o json > security/assessments-$(date +%Y%m%d).json
# Join and summarize using parse scriptpython security/parse_defender.py \ security/metadata-$(date +%Y%m%d).json \ security/assessments-$(date +%Y%m%d).json \ > security/findings-$(date +%Y%m%d).jsonCross-reference findings against the register (defender-register.md) and existing Jira tickets (JQL: project = DEVOPS AND labels = Defender). Create new tickets for any untracked findings.
Triage Workflow
- New finding arrives — Create Jira Task in DEVOPS project
- Set label:
Defender+ severity label (e.g.,defender-high) + env labels - Set priority to match severity Epic
- Set Epic Link (
customfield_10007) to the matching severity Epic - Description: Include Defender recommendation name, affected resources, resource count
- Set label:
- Initial assessment (within 3 business days of discovery)
- Engineer reviews the finding and affected resources
- Confirms Defender severity is appropriate (or proposes override with justification)
- Classifies resources as prod/non-prod, adds env labels
- Checks Defender portal for risk-based status, adds risk labels if applicable
- Categorization review
- Team lead confirms or adjusts severity
- If “Non-Issue” or “Won’t Do”, see approval process below
Wave Prioritization
Remediation is prioritized by severity and environment:
| Wave | Scope | JQL | Timeline |
|---|---|---|---|
| 1 | High + prod | labels = Defender AND labels = env-prod AND parent = DEVOPS-82 AND status != Done | Immediate |
| 2 | High + non-prod, Medium + prod | Combined query | Next sprint |
| 3 | Medium + non-prod | labels = Defender AND labels = env-nonprod AND parent = DEVOPS-83 AND status != Done | Following sprint |
| 4 | Low + prod | labels = Defender AND labels = env-prod AND parent = DEVOPS-84 AND status != Done | Backlog |
| 5 | Low + non-prod | labels = Defender AND labels = env-nonprod AND parent = DEVOPS-84 AND status != Done | Backlog |
Items with risk-critical or attack-path labels should be prioritized within their wave.
”Won’t Do” Approval Process
When a finding is evaluated and the recommendation should NOT be implemented:
- Engineer adds comment to the Jira ticket with:
- Justification: Why this will not be implemented
- Compensating controls: What mitigations exist instead
- Risk acceptance: What residual risk remains
- Engineer moves ticket to the “Defender - Won’t Do (Pending Approval)” Epic (DEVOPS-86)
- Team lead must approve by adding a comment with
[APPROVED - Won't Do] - Only after approval can the ticket be moved to Done
- If team lead disagrees, they reassign back with revised instructions
IMPORTANT: No finding may be marked as “Won’t Do” without team lead approval.
Release Notes
When Defender findings are resolved, update the release notes:
- Use the template at
security/release-notes/TEMPLATE.md - Create a new file:
security/release-notes/YYYY-MM-DD-batch-N.md - Document each resolved finding following the template format
- Include: What happened, Solution steps, QA considerations, Deployment considerations
Ongoing Cadence
| Frequency | Activity |
|---|---|
| Immediately | High findings affecting prod go into current sprint |
| Monthly | Pull latest Defender findings, create tickets for new items, update risk labels |
| Sprint planning | Include Defender items per wave prioritization |
| Sprint close | Generate release notes for resolved Defender items |
| Quarterly | Full review of all open Defender items with team lead |
Quick JQL Reference
| Filter | JQL |
|---|---|
| All Defender items | project = DEVOPS AND labels = Defender ORDER BY priority DESC |
| Open items | project = DEVOPS AND labels = Defender AND status != Done ORDER BY priority DESC |
| High | project = DEVOPS AND labels = Defender AND parent = DEVOPS-82 |
| Medium | project = DEVOPS AND labels = Defender AND parent = DEVOPS-83 |
| Low | project = DEVOPS AND labels = Defender AND parent = DEVOPS-84 |
| Prod + High | project = DEVOPS AND labels in (Defender, env-prod) AND parent = DEVOPS-82 AND status != Done |
| Non-prod only | project = DEVOPS AND labels = Defender AND labels = env-nonprod AND labels not in (env-prod) AND status != Done |
| Risk Critical | project = DEVOPS AND labels in (Defender, risk-critical) AND status != Done |
| Attack Path | project = DEVOPS AND labels in (Defender, attack-path) AND status != Done |