Files
mukul975 c21af3347e Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal
- Add scripts/agent.py and references/api-reference.md to all remaining skills
- Update all 648 LICENSE files: copyright now reads 'Mahipal'
- Add implementing-security-monitoring-with-datadog (new skill with full anatomy)
- All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
2026-03-11 00:22:12 +01:00

223 lines
8.6 KiB
Python

#!/usr/bin/env python3
"""Agent for assessing identity verification controls in zero trust architecture."""
import json
import argparse
from datetime import datetime
from collections import Counter
CISA_ZT_IDENTITY_LEVELS = {
"traditional": {
"description": "Password-based auth, static policies",
"score": 1,
},
"initial": {
"description": "MFA deployed, basic conditional access",
"score": 2,
},
"advanced": {
"description": "Phishing-resistant MFA, risk-based access",
"score": 3,
},
"optimal": {
"description": "Continuous verification, passwordless, behavioral analytics",
"score": 4,
},
}
def assess_authentication_methods(auth_config):
"""Assess authentication method strength against zero trust requirements."""
findings = []
methods = auth_config.get("methods", auth_config.get("authentication", {}))
if isinstance(methods, dict):
mfa_enabled = methods.get("mfa_enabled", False)
phishing_resistant = methods.get("phishing_resistant_mfa", False)
passwordless = methods.get("passwordless", False)
fido2 = methods.get("fido2_enabled", False)
sso = methods.get("sso_enabled", False)
if not mfa_enabled:
findings.append({"control": "MFA", "status": "MISSING",
"severity": "CRITICAL"})
elif not phishing_resistant:
findings.append({"control": "Phishing-resistant MFA", "status": "MISSING",
"severity": "HIGH",
"recommendation": "Deploy FIDO2 or certificate-based auth"})
if not fido2:
findings.append({"control": "FIDO2/WebAuthn", "status": "NOT_DEPLOYED",
"severity": "MEDIUM"})
if not passwordless:
findings.append({"control": "Passwordless authentication",
"status": "NOT_DEPLOYED", "severity": "MEDIUM"})
if not sso:
findings.append({"control": "SSO", "status": "NOT_DEPLOYED",
"severity": "HIGH"})
return findings
def assess_conditional_access(policies_path):
"""Assess conditional access policies for zero trust alignment."""
with open(policies_path) as f:
policies = json.load(f)
items = policies if isinstance(policies, list) else policies.get("policies", [])
findings = []
required_signals = ["device_compliance", "location", "risk_level",
"application", "user_group"]
covered_signals = set()
for policy in items:
conditions = policy.get("conditions", {})
for signal in required_signals:
if conditions.get(signal) or signal in str(conditions):
covered_signals.add(signal)
if policy.get("grant_controls", {}).get("operator") == "OR":
findings.append({
"policy": policy.get("name", ""),
"issue": "Grant controls use OR (should be AND)",
"severity": "HIGH",
})
if not policy.get("state", "").lower() in ("enabled", "on"):
findings.append({
"policy": policy.get("name", ""),
"issue": "Policy not enabled",
"severity": "MEDIUM",
})
missing = set(required_signals) - covered_signals
for signal in missing:
findings.append({
"control": f"Conditional access signal: {signal}",
"status": "NOT_COVERED",
"severity": "HIGH",
})
return {"findings": findings, "covered_signals": list(covered_signals),
"missing_signals": list(missing)}
def assess_identity_maturity(config):
"""Assess identity pillar maturity against CISA Zero Trust Maturity Model."""
scores = {}
categories = {
"authentication": {
"checks": ["mfa_enforced", "phishing_resistant_mfa", "passwordless",
"continuous_auth"],
},
"identity_stores": {
"checks": ["centralized_idp", "cloud_identity", "directory_sync",
"identity_federation"],
},
"risk_assessment": {
"checks": ["risk_based_access", "behavioral_analytics",
"impossible_travel_detection", "session_risk_scoring"],
},
"visibility": {
"checks": ["identity_audit_logging", "real_time_monitoring",
"identity_analytics_dashboard", "automated_anomaly_detection"],
},
}
for category, info in categories.items():
implemented = sum(1 for check in info["checks"]
if config.get(category, {}).get(check, False))
total = len(info["checks"])
ratio = implemented / total if total else 0
if ratio >= 0.9:
level = "optimal"
elif ratio >= 0.6:
level = "advanced"
elif ratio >= 0.3:
level = "initial"
else:
level = "traditional"
scores[category] = {
"implemented": implemented,
"total": total,
"ratio": round(ratio, 2),
"maturity_level": level,
"score": CISA_ZT_IDENTITY_LEVELS[level]["score"],
}
avg_score = sum(s["score"] for s in scores.values()) / len(scores) if scores else 0
for level_name, level_info in CISA_ZT_IDENTITY_LEVELS.items():
if level_info["score"] >= avg_score:
overall_level = level_name
break
else:
overall_level = "traditional"
return {"categories": scores, "overall_score": round(avg_score, 1),
"overall_level": overall_level}
def analyze_auth_events(events_path):
"""Analyze authentication events for zero trust insights."""
with open(events_path) as f:
events = json.load(f)
items = events if isinstance(events, list) else events.get("events", [])
by_method = Counter(e.get("auth_method", "unknown") for e in items)
by_result = Counter(e.get("result", "unknown") for e in items)
risky = [e for e in items if e.get("risk_level", "").lower() in ("high", "critical")]
mfa_bypassed = [e for e in items if e.get("mfa_bypassed", False)]
return {
"total_events": len(items),
"by_method": dict(by_method),
"by_result": dict(by_result),
"high_risk_events": len(risky),
"mfa_bypass_events": len(mfa_bypassed),
"password_only_rate": round(
by_method.get("password", 0) / len(items) * 100, 1) if items else 0,
}
def main():
parser = argparse.ArgumentParser(description="Zero Trust Identity Verification Agent")
parser.add_argument("--auth-config", help="Authentication config JSON")
parser.add_argument("--policies", help="Conditional access policies JSON")
parser.add_argument("--maturity-config", help="Identity maturity assessment config JSON")
parser.add_argument("--auth-events", help="Authentication events log JSON")
parser.add_argument("--action", choices=["auth", "policies", "maturity", "events", "full"],
default="full")
parser.add_argument("--output", default="zt_identity_report.json")
args = parser.parse_args()
report = {"generated_at": datetime.utcnow().isoformat(), "results": {}}
if args.action in ("auth", "full") and args.auth_config:
with open(args.auth_config) as f:
config = json.load(f)
findings = assess_authentication_methods(config)
report["results"]["auth_assessment"] = findings
critical = sum(1 for f in findings if f.get("severity") == "CRITICAL")
print(f"[+] Auth findings: {len(findings)}, {critical} critical")
if args.action in ("policies", "full") and args.policies:
result = assess_conditional_access(args.policies)
report["results"]["conditional_access"] = result
print(f"[+] Missing signals: {result['missing_signals']}")
if args.action in ("maturity", "full") and args.maturity_config:
with open(args.maturity_config) as f:
config = json.load(f)
result = assess_identity_maturity(config)
report["results"]["maturity"] = result
print(f"[+] Identity maturity: {result['overall_level']} (score: {result['overall_score']})")
if args.action in ("events", "full") and args.auth_events:
result = analyze_auth_events(args.auth_events)
report["results"]["events"] = result
print(f"[+] Auth events: {result['total_events']}, password-only: {result['password_only_rate']}%")
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"[+] Report saved to {args.output}")
if __name__ == "__main__":
main()