Files
vm-cloudflare/mcp/waf_intelligence/__main__.py
Vault Sovereign 37a867c485 Initial commit: Cloudflare infrastructure with WAF Intelligence
- Complete Cloudflare Terraform configuration (DNS, WAF, tunnels, access)
- WAF Intelligence MCP server with threat analysis and ML classification
- GitOps automation with PR workflows and drift detection
- Observatory monitoring stack with Prometheus/Grafana
- IDE operator rules for governed development
- Security playbooks and compliance frameworks
- Autonomous remediation and state reconciliation
2025-12-16 18:31:53 +00:00

133 lines
4.0 KiB
Python

from __future__ import annotations
import argparse
import json
import sys
from dataclasses import asdict
from pathlib import Path
from typing import Any, Dict, List
from .orchestrator import WAFInsight, WAFIntelligence
def _insight_to_dict(insight: WAFInsight) -> Dict[str, Any]:
"""Convert a WAFInsight dataclass into a plain dict."""
return asdict(insight)
def _has_error(insights: List[WAFInsight]) -> bool:
"""Return True if any violation is error-severity."""
for insight in insights:
if insight.violation and insight.violation.severity == "error":
return True
return False
def run_cli(argv: List[str] | None = None) -> int:
parser = argparse.ArgumentParser(
prog="python -m mcp.waf_intelligence",
description="Analyze Cloudflare WAF Terraform configs and produce curated security + compliance insights.",
)
parser.add_argument(
"--file",
"-f",
required=True,
help="Path to the Terraform WAF file (e.g. terraform/waf.tf)",
)
parser.add_argument(
"--limit",
"-n",
type=int,
default=3,
help="Maximum number of high-priority insights to return (default: 3)",
)
parser.add_argument(
"--format",
"-o",
choices=["text", "json"],
default="text",
help="Output format: text (human-readable) or json (machine-readable). Default: text.",
)
parser.add_argument(
"--fail-on-error",
action="store_true",
help="Exit with non-zero code if any error-severity violations are found.",
)
args = parser.parse_args(argv)
path = Path(args.file)
if not path.exists():
print(f"[error] file not found: {path}", file=sys.stderr)
return 1
intel = WAFIntelligence()
insights = intel.analyze_and_recommend(str(path), limit=args.limit)
if args.format == "json":
payload = {
"file": str(path),
"insights": [_insight_to_dict(insight) for insight in insights],
}
print(json.dumps(payload, indent=2))
if args.fail_on_error and _has_error(insights):
print(
"[waf_intel] error-severity violations present, failing as requested.",
file=sys.stderr,
)
return 2
return 0
print(f"\nWAF Intelligence Report for: {path}\n{'-' * 72}")
if not insights:
print("No high-severity, high-confidence issues detected based on current heuristics.")
return 0
for idx, insight in enumerate(insights, start=1):
print(f"\nInsight #{idx}")
print("-" * 40)
if insight.violation:
violation = insight.violation
print(f"Problem : {violation.message}")
print(f"Severity : {violation.severity.upper()}")
print(f"Confidence: {int(violation.confidence * 100)}%")
if violation.location:
print(f"Location : {violation.location}")
if violation.hint:
print(f"Remediate : {violation.hint}")
if insight.suggested_rule:
rule = insight.suggested_rule
print("\nSuggested Rule:")
print(f" Name : {rule.name}")
print(f" Severity: {rule.severity.upper()}")
print(f" Impact : {int(rule.impact_score * 100)}%")
print(f" Effort : {int(rule.effort_score * 100)}%")
print(f" Summary : {rule.description}")
if insight.mappings:
print("\nCompliance Mapping:")
for mapping in insight.mappings:
print(f" - {mapping.framework} {mapping.control_id}: {mapping.description}")
print()
if args.fail_on_error and _has_error(insights):
print(
"[waf_intel] error-severity violations present, failing as requested.",
file=sys.stderr,
)
return 2
return 0
def main() -> None:
raise SystemExit(run_cli())
if __name__ == "__main__":
main()