#!/usr/bin/env python3 """ CISA Zero Trust Maturity Model Assessment and Roadmap Generator. Evaluates organizational zero trust maturity across the five CISA ZTMM pillars (Identity, Devices, Networks, Applications, Data) and three cross-cutting capabilities (Visibility & Analytics, Automation & Orchestration, Governance). Generates gap analysis, prioritized roadmap, and compliance mapping. """ import json import csv import datetime from dataclasses import dataclass, field from enum import IntEnum from typing import Optional from pathlib import Path class MaturityStage(IntEnum): TRADITIONAL = 0 INITIAL = 1 ADVANCED = 2 OPTIMAL = 3 PILLAR_FUNCTIONS = { "Identity": [ "authentication", "identity_stores", "risk_assessment", "access_management", "identity_lifecycle", "visibility_analytics", "automation_orchestration", "governance", ], "Devices": [ "policy_enforcement", "asset_management", "device_compliance", "device_threat_protection", "visibility_analytics", "automation_orchestration", "governance", ], "Networks": [ "network_segmentation", "threat_protection", "encryption", "network_resilience", "visibility_analytics", "automation_orchestration", "governance", ], "Applications": [ "access_authorization", "threat_protection", "accessibility", "application_security", "visibility_analytics", "automation_orchestration", "governance", ], "Data": [ "data_inventory", "data_categorization", "data_availability", "data_access", "data_encryption", "visibility_analytics", "automation_orchestration", "governance", ], } OMB_M2209_REQUIREMENTS = { "Identity": { "requirement": "Agency staff use enterprise-managed identities with phishing-resistant MFA", "target_stage": MaturityStage.ADVANCED, "key_actions": [ "Deploy FIDO2/WebAuthn for all users", "Integrate identity provider with all applications", "Implement authorization based on user attributes", ], }, "Devices": { "requirement": "Federal government has a complete inventory of authorized devices and can prevent/detect/respond to incidents", "target_stage": MaturityStage.ADVANCED, "key_actions": [ "Deploy EDR on all endpoints", "Maintain real-time asset inventory", "Enforce device compliance before access", ], }, "Networks": { "requirement": "Agencies encrypt all DNS and HTTP traffic within their environment", "target_stage": MaturityStage.ADVANCED, "key_actions": [ "Encrypt all DNS traffic (DoH/DoT)", "Enforce HTTPS for all web traffic", "Implement network microsegmentation", ], }, "Applications": { "requirement": "Agencies treat all applications as internet-connected and routinely test them", "target_stage": MaturityStage.ADVANCED, "key_actions": [ "Integrate SAST/DAST into CI/CD", "Remove application access from VPN dependencies", "Implement application-level access policies", ], }, "Data": { "requirement": "Agencies have thorough data categorization and employ automated tools", "target_stage": MaturityStage.ADVANCED, "key_actions": [ "Implement data classification scheme", "Deploy automated data tagging", "Enable DLP across all data channels", ], }, } @dataclass class FunctionAssessment: function_name: str current_stage: MaturityStage target_stage: MaturityStage evidence: str = "" gaps: list = field(default_factory=list) recommendations: list = field(default_factory=list) @dataclass class PillarAssessment: pillar_name: str functions: list = field(default_factory=list) overall_stage: MaturityStage = MaturityStage.TRADITIONAL compliance_gap: bool = False def calculate_overall(self): if not self.functions: return scores = [f.current_stage.value for f in self.functions] avg = sum(scores) / len(scores) self.overall_stage = MaturityStage(int(avg)) def check_compliance(self): req = OMB_M2209_REQUIREMENTS.get(self.pillar_name) if req: self.compliance_gap = self.overall_stage < req["target_stage"] @dataclass class RoadmapItem: pillar: str function_name: str current_stage: str target_stage: str priority: int # 1=highest, 4=lowest effort: str # low, medium, high recommendations: list = field(default_factory=list) dependencies: list = field(default_factory=list) class ZTMMAssessment: """Full CISA Zero Trust Maturity Model assessment engine.""" def __init__(self, organization_name: str): self.organization = organization_name self.assessment_date = datetime.datetime.now().isoformat() self.pillar_assessments: dict[str, PillarAssessment] = {} self.roadmap: list[RoadmapItem] = [] def assess_function( self, pillar: str, function_name: str, current_stage: int, target_stage: int = 3, evidence: str = "", gaps: Optional[list] = None, ) -> FunctionAssessment: current = MaturityStage(current_stage) target = MaturityStage(target_stage) fa = FunctionAssessment( function_name=function_name, current_stage=current, target_stage=target, evidence=evidence, gaps=gaps or [], ) if pillar not in self.pillar_assessments: self.pillar_assessments[pillar] = PillarAssessment(pillar_name=pillar) self.pillar_assessments[pillar].functions.append(fa) return fa def calculate_maturity(self): for pa in self.pillar_assessments.values(): pa.calculate_overall() pa.check_compliance() def generate_roadmap(self) -> list[RoadmapItem]: self.roadmap = [] effort_map = {0: "high", 1: "medium", 2: "low", 3: "low"} for pillar_name, pa in self.pillar_assessments.items(): for func in pa.functions: if func.current_stage < func.target_stage: gap = func.target_stage.value - func.current_stage.value next_stage = MaturityStage(func.current_stage.value + 1) item = RoadmapItem( pillar=pillar_name, function_name=func.function_name, current_stage=func.current_stage.name, target_stage=next_stage.name, priority=max(1, 4 - gap), effort=effort_map.get(func.current_stage.value, "high"), recommendations=func.recommendations, ) self.roadmap.append(item) self.roadmap.sort(key=lambda x: (x.priority, x.effort != "low")) return self.roadmap def get_compliance_status(self) -> dict: status = {} for pillar_name, pa in self.pillar_assessments.items(): req = OMB_M2209_REQUIREMENTS.get(pillar_name, {}) status[pillar_name] = { "current_stage": pa.overall_stage.name, "required_stage": req.get("target_stage", MaturityStage.ADVANCED).name, "compliant": not pa.compliance_gap, "requirement": req.get("requirement", "N/A"), "key_actions": req.get("key_actions", []), } return status def get_summary(self) -> dict: summary = { "organization": self.organization, "assessment_date": self.assessment_date, "pillars": {}, "overall_maturity": "TRADITIONAL", } stages = [] for name, pa in self.pillar_assessments.items(): summary["pillars"][name] = { "stage": pa.overall_stage.name, "score": pa.overall_stage.value, "functions_assessed": len(pa.functions), "compliance_gap": pa.compliance_gap, } stages.append(pa.overall_stage.value) if stages: avg = sum(stages) / len(stages) summary["overall_maturity"] = MaturityStage(int(avg)).name summary["overall_score"] = round(avg, 2) return summary def export_report(self, output_path: str): report = { "summary": self.get_summary(), "compliance_status": self.get_compliance_status(), "roadmap": [ { "pillar": r.pillar, "function": r.function_name, "current": r.current_stage, "target": r.target_stage, "priority": r.priority, "effort": r.effort, } for r in self.roadmap ], "detailed_assessments": {}, } for name, pa in self.pillar_assessments.items(): report["detailed_assessments"][name] = { "overall_stage": pa.overall_stage.name, "functions": [ { "name": f.function_name, "current": f.current_stage.name, "target": f.target_stage.name, "evidence": f.evidence, "gaps": f.gaps, } for f in pa.functions ], } path = Path(output_path) path.parent.mkdir(parents=True, exist_ok=True) with open(path, "w") as f: json.dump(report, f, indent=2) return report def export_csv(self, output_path: str): path = Path(output_path) path.parent.mkdir(parents=True, exist_ok=True) with open(path, "w", newline="") as f: writer = csv.writer(f) writer.writerow([ "Pillar", "Function", "Current Stage", "Target Stage", "Gap", "Priority", "Effort", "Evidence" ]) for name, pa in self.pillar_assessments.items(): for func in pa.functions: gap = func.target_stage.value - func.current_stage.value writer.writerow([ name, func.function_name, func.current_stage.name, func.target_stage.name, gap, max(1, 4 - gap), "high" if func.current_stage == MaturityStage.TRADITIONAL else "medium", func.evidence, ]) def run_sample_assessment(): """Run a sample assessment demonstrating the ZTMM assessment process.""" assessment = ZTMMAssessment("Example Federal Agency") # Identity Pillar Assessment assessment.assess_function("Identity", "authentication", 1, 3, evidence="MFA deployed for 60% of users, not phishing-resistant", gaps=["No FIDO2/WebAuthn deployment", "Service accounts lack MFA"]) assessment.assess_function("Identity", "identity_stores", 1, 3, evidence="Centralized AD, partial cloud identity integration") assessment.assess_function("Identity", "risk_assessment", 0, 3, evidence="No risk-based authentication in place") assessment.assess_function("Identity", "access_management", 1, 3, evidence="Basic RBAC, no attribute-based access control") assessment.assess_function("Identity", "identity_lifecycle", 1, 3, evidence="Manual provisioning, no HR integration") # Devices Pillar Assessment assessment.assess_function("Devices", "policy_enforcement", 1, 3, evidence="MDM deployed, basic compliance checks") assessment.assess_function("Devices", "asset_management", 1, 3, evidence="Partial inventory, no IoT coverage") assessment.assess_function("Devices", "device_compliance", 0, 3, evidence="No real-time compliance checking") assessment.assess_function("Devices", "device_threat_protection", 1, 3, evidence="EDR on 70% of endpoints") # Networks Pillar Assessment assessment.assess_function("Networks", "network_segmentation", 0, 3, evidence="Flat network, basic VLAN segmentation only") assessment.assess_function("Networks", "threat_protection", 1, 3, evidence="Perimeter firewall, no NDR") assessment.assess_function("Networks", "encryption", 1, 3, evidence="TLS for external, plaintext internal") assessment.assess_function("Networks", "network_resilience", 1, 3, evidence="Basic redundancy, no SD-WAN") # Applications Pillar Assessment assessment.assess_function("Applications", "access_authorization", 1, 3, evidence="VPN-based access for internal apps") assessment.assess_function("Applications", "threat_protection", 1, 3, evidence="WAF for public apps only") assessment.assess_function("Applications", "application_security", 0, 3, evidence="Annual pen tests, no CI/CD security integration") # Data Pillar Assessment assessment.assess_function("Data", "data_inventory", 0, 3, evidence="No comprehensive data inventory") assessment.assess_function("Data", "data_categorization", 1, 3, evidence="Basic classification, manual process") assessment.assess_function("Data", "data_access", 1, 3, evidence="Role-based access, no fine-grained controls") assessment.assess_function("Data", "data_encryption", 1, 3, evidence="Encryption at rest for databases, not all storage") # Calculate and report assessment.calculate_maturity() roadmap = assessment.generate_roadmap() print("=" * 70) print(f"CISA ZTMM Assessment: {assessment.organization}") print(f"Date: {assessment.assessment_date}") print("=" * 70) summary = assessment.get_summary() print(f"\nOverall Maturity: {summary['overall_maturity']} (Score: {summary.get('overall_score', 'N/A')})") print("\nPillar Maturity Scores:") for pillar, data in summary["pillars"].items(): compliance = " [COMPLIANCE GAP]" if data["compliance_gap"] else " [COMPLIANT]" print(f" {pillar:20s}: {data['stage']:12s} (Score: {data['score']}){compliance}") print("\nOMB M-22-09 Compliance Status:") compliance = assessment.get_compliance_status() for pillar, status in compliance.items(): icon = "PASS" if status["compliant"] else "FAIL" print(f" [{icon}] {pillar}: {status['current_stage']} / Required: {status['required_stage']}") print(f"\nPrioritized Roadmap ({len(roadmap)} items):") for i, item in enumerate(roadmap[:10], 1): print(f" {i}. [{item.pillar}] {item.function_name}: " f"{item.current_stage} -> {item.target_stage} " f"(Priority: {item.priority}, Effort: {item.effort})") # Export reports assessment.export_report("ztmm_assessment_report.json") assessment.export_csv("ztmm_assessment_report.csv") print("\nReports exported: ztmm_assessment_report.json, ztmm_assessment_report.csv") if __name__ == "__main__": run_sample_assessment()