Security Metrics and Reporting


Introduction

Security metrics translate technical security operations into business-relevant information that drives decision-making. Without metrics, security programs cannot demonstrate value, identify weaknesses, or justify resource allocation. Effective security reporting addresses multiple audiences — from technical teams to the board of directors — each with different information needs.

KPIs vs KRIs

Key Performance Indicators (KPIs)

KPIs measure the efficiency and effectiveness of security operations.




class SecurityKPI:


def __init__(self):


self.metrics = {}




def calculate_mttd(self, detection_times):


"""Mean Time to Detect — average time from compromise to detection."""


if not detection_times:


return None


return sum(detection_times) / len(detection_times)




def calculate_mttr(self, response_times):


"""Mean Time to Respond — average time from detection to containment."""


if not response_times:


return None


return sum(response_times) / len(response_times)




def calculate_coverage_rate(self, monitored_assets, total_assets):


"""Percentage of assets under monitoring."""


if total_assets == 0:


return 0


return (monitored_assets / total_assets) * 100




def calculate_patch_compliance(self, patched_systems, vulnerable_systems):


"""Percentage of systems patched within SLA."""


total = patched_systems + vulnerable_systems


if total == 0:


return 100


return (patched_systems / total) * 100





Key Risk Indicators (KRIs)

KRIs measure the level of security risk exposure.




class SecurityKRI:


def calculate_vulnerability_risk_score(self, vulnerabilities):


"""Weighted risk score based on CVSS and asset criticality."""


total_risk = 0


for vuln in vulnerabilities:


# CVSS score * asset criticality multiplier


risk = vuln['cvss'] * (vuln['asset_criticality'] / 5)




# Exploit availability multiplier


if vuln.get('exploit_available'):


risk *= 1.5


if vuln.get('in_wild'):


risk *= 2.0




total_risk += risk




return total_risk




def calculate_mean_time_to_patch(self, patch_times):


"""Average time to apply security patches by severity."""


categories = {'critical': [], 'high': [], 'medium': [], 'low': []}




for patch in patch_times:


categories[patch['severity']].append(patch['hours_to_patch'])




return {


severity: sum(times) / len(times) if times else 0


for severity, times in categories.items()


}





Dashboard Design

Effective dashboards present the right information at the right level of detail for the audience.

Executive Dashboard




def generate_executive_dashboard(metrics):


"""Board-level dashboard — strategic, summary, trend-focused."""


return {


'security_posture_score': metrics['posture_score'], # 0-100


'risk_trend': metrics['risk_trend'], # improving/stable/declining


'incidents_this_quarter': {


'total': metrics['incident_count'],


'critical': metrics['critical_incidents'],


'trend': metrics['incident_trend']


},


'top_risks': [


{'risk': 'Unpatched critical vulnerabilities',


'status': 'on_track', 'due_date': '2026-06-01'},


{'risk': 'Cloud misconfigurations',


'status': 'at_risk', 'due_date': '2026-05-15'},


],


'compliance_status': {


'soc2': 'compliant',


'pci_dss': 'compliant',


'hipaa': 'in_progress'


},


'budget_utilization': {


'allocated': 2500000,


'spent': 1850000,


'remaining': 650000


}


}





Operational Dashboard




def generate_operational_dashboard(soc_metrics):


"""SOC-level dashboard — tactical, detailed, real-time."""


return {


'alert_volume': {


'today': 847,


'change': '+12%',


'by_severity': {


'critical': 3,


'high': 27,


'medium': 145,


'low': 672


}


},


'mean_times': {


'mttd': '45 minutes',


'mttr': '3.2 hours',


'triage_time': '8 minutes'


},


'queue_status': {


'unassigned': 23,


'in_progress': 45,


'escalated': 12


},


'false_positive_rate': '28%',


'coverage': {


'endpoints': '98.5%',


'servers': '100%',


'cloud_accounts': '95%'


}


}





Board Reporting Framework




quarterly_board_report:


sections:


- title: "Executive Summary"


content:


- "Security posture improved from 72 to 78 (target: 80)"


- "Zero critical incidents this quarter"


- "Three compliance audits passed"




- title: "Incident Summary"


metrics:


- name: "Total Incidents"


value: 12


trend: "decreasing"


- name: "Mean Time to Detect"


value: "45 min"


target: "< 60 min"


status: "on_track"


- name: "Mean Time to Respond"


value: "3.2 hrs"


target: "< 4 hrs"


status: "on_track"


- name: "Phishing Click Rate"


value: "4.2%"


target: "< 5%"


status: "on_track"




- title: "Risk Profile"


risks:


- id: "R-001"


description: "Third-party vendor access to production"


likelihood: "medium"


impact: "high"


mitigation: "Vendor access review in progress"


target_date: "2026-07-01"




- title: "Compliance Status"


frameworks:


- name: "SOC 2 Type II"


status: "compliant"


last_audit: "2026-03-15"


- name: "PCI DSS 4.0"


status: "compliant"


last_audit: "2026-02-28"


- name: "ISO 27001"


status: "in_progress"


target: "2026-09-01"




- title: "Resource Allocation"


budget:


allocated: "$2.5M"


spent: "$1.85M (74%)"


key_investments:


- "EDR platform upgrade: $450K"


- "Security awareness training: $85K"


- "Penetration testing: $120K"





Security Scorecards




def generate_team_scorecard(metrics):


"""Department-level scorecard for security team performance."""


thresholds = {


'patch_compliance': {'good': 95, 'acceptable': 85},


'coverage': {'good': 98, 'acceptable': 90},


'false_positive_rate': {'good': 20, 'acceptable': 35},


'mttd_minutes': {'good': 30, 'acceptable': 60},


'mttr_hours': {'good': 2, 'acceptable': 4},


}




scorecard = {}


for metric, value in metrics.items():


if metric not in thresholds:


continue


threshold = thresholds[metric]


if value >= threshold['good']:


scorecard[metric] = 'GREEN'


elif value >= threshold['acceptable']:


scorecard[metric] = 'YELLOW'


else:


scorecard[metric] = 'RED'




return scorecard





Industry Benchmarks




industry_benchmarks:


mttd:


top_performer: "< 1 hour"


average: "24-48 hours"


below_average: "> 1 week"




mttr:


top_performer: "< 2 hours"


average: "4-8 hours"


below_average: "> 24 hours"




vulnerability_remediation:


critical: "15 days (top), 30 days (average)"


high: "30 days (top), 60 days (average)"




security_spend:


as_percentage_of_it: "5-10% (recommended)"


per_employee: "$1,500-2,500 (enterprise)"





Conclusion

Security metrics must be meaningful, measurable, and actionable. Distinguish between KPIs that measure operational effectiveness and KRIs that measure risk exposure. Tailor dashboards for each audience — executives need strategic trends and risk summaries, while SOC teams need real-time operational data. Benchmark against industry peers, track trends over time (not just snapshots), and always tie metrics back to business impact and risk reduction.