{
  "example": "Synthetic, deliberately insecure visualization input. Not a deployment template or live cloud scan.",
  "resources": 9,
  "boundaries": 8,
  "review": {
    "findings": [
      {
        "id": "public-database",
        "severity": "critical",
        "category": "exposure",
        "title": "Database \"orders\" is publicly accessible",
        "targets": [
          "aws_db_instance.orders"
        ],
        "why": "The database is provisioned with a public endpoint, so it is reachable from outside your network perimeter.",
        "risk": "Credential stuffing, brute force, and any unpatched engine CVE become internet-facing. This is one of the most commonly exploited cloud misconfigurations.",
        "bestPractice": "Place the database in private subnets with no public endpoint and reach it through a bastion, VPN, or private link.",
        "impact": "Removes the database from the internet-reachable attack surface entirely."
      },
      {
        "id": "security-group-open",
        "severity": "critical",
        "category": "exposure",
        "title": "Security group allows the internet to reach port 22",
        "targets": [
          "aws_security_group.web"
        ],
        "why": "An ingress rule permits 0.0.0.0/0 on port 22, which is every address on the internet.",
        "risk": "Administrative and database ports exposed to the internet are scanned continuously and are a primary initial-access vector.",
        "bestPractice": "Restrict ingress to known CIDRs, a load balancer security group, or a bastion. Use SSM Session Manager or an identity-aware proxy instead of open SSH.",
        "impact": "Cuts the reachable attack surface from the whole internet to a named set of sources."
      },
      {
        "id": "no-database-backup",
        "severity": "critical",
        "category": "reliability",
        "title": "Database \"orders\" has backups disabled",
        "targets": [
          "aws_db_instance.orders"
        ],
        "why": "Backup retention is set to 0 days, so no automated backup is taken or kept.",
        "risk": "Accidental deletion, corruption, or a bad migration is unrecoverable. There is no point-in-time restore.",
        "bestPractice": "Set a retention period that matches your recovery point objective, commonly 7 to 35 days.",
        "impact": "Turns an unrecoverable data-loss event into a restore measured in minutes."
      },
      {
        "id": "no-encryption-at-rest",
        "severity": "high",
        "category": "exposure",
        "title": "1 resource has encryption at rest disabled",
        "targets": [
          "aws_db_instance.orders"
        ],
        "why": "Encryption at rest is explicitly turned off on these resources.",
        "risk": "Snapshots, backups, and underlying volumes are readable by anyone who obtains them, and most compliance frameworks treat this as a control failure.",
        "bestPractice": "Enable encryption at rest with a customer-managed key so key access is auditable and revocable.",
        "impact": "Closes a control gap that SOC 2, ISO 27001, HIPAA, and PCI all test for."
      },
      {
        "id": "single-az-database",
        "severity": "high",
        "category": "reliability",
        "title": "2 databases run in a single availability zone",
        "targets": [
          "aws_db_instance.orders",
          "aws_elasticache_cluster.sessions"
        ],
        "why": "The database has no standby in a second zone, so its availability is tied to one physical failure domain.",
        "risk": "A single zone outage takes the database offline with no automatic failover, and recovery depends on restoring from backup.",
        "bestPractice": "Enable multi-AZ (or a regional/zonal replica on GCP and Azure) so a standby is promoted automatically.",
        "impact": "Recovery time drops from hours of restore work to seconds of automatic failover."
      },
      {
        "id": "auto-assign-public-ip",
        "severity": "medium",
        "category": "exposure",
        "title": "1 subnet auto-assign public IPs",
        "targets": [
          "aws_subnet.public_a"
        ],
        "why": "Instances launched into these subnets receive a public IP address by default.",
        "risk": "A workload intended to be internal becomes internet-reachable simply by being launched in the wrong subnet.",
        "bestPractice": "Disable automatic public IP assignment and place internet-facing entry points behind a load balancer instead.",
        "impact": "Public exposure becomes an explicit decision rather than a default."
      },
      {
        "id": "single-nat-gateway",
        "severity": "medium",
        "category": "network",
        "title": "A single NAT gateway serves multiple availability zones",
        "targets": [
          "aws_nat_gateway.nat"
        ],
        "why": "There are 2 availability zones but only one NAT gateway.",
        "risk": "The NAT gateway is a single point of failure for all outbound traffic, and cross-AZ NAT traffic is billed as inter-zone transfer.",
        "bestPractice": "Run one NAT gateway per availability zone with zone-local routes.",
        "impact": "Removes a shared failure point and stops paying cross-AZ charges on all egress."
      },
      {
        "id": "no-waf",
        "severity": "medium",
        "category": "network",
        "title": "No web application firewall in front of the load balancer",
        "targets": [
          "aws_lb.edge"
        ],
        "why": "The architecture terminates public HTTP traffic at a load balancer with no WAF attached.",
        "risk": "Injection, path traversal, and bot traffic reach the application directly, and there is no rate limiting at the edge.",
        "bestPractice": "Attach a WAF with a managed rule set covering the OWASP Top 10, plus rate-based rules for abusive clients.",
        "impact": "Blocks common exploit traffic before it reaches application code."
      },
      {
        "id": "no-logging",
        "severity": "medium",
        "category": "operations",
        "title": "No log group or logging destination is defined",
        "targets": [
          "aws_ecs_service.api"
        ],
        "why": "The configuration provisions workloads but declares nowhere for their logs to go.",
        "risk": "Incidents are diagnosed without evidence, and most compliance frameworks require retained audit logs.",
        "bestPractice": "Declare log groups with an explicit retention period and ship application and platform logs to them.",
        "impact": "Turns incident investigation from guesswork into evidence, and satisfies a control auditors test."
      },
      {
        "id": "unattached-volume",
        "severity": "low",
        "category": "cost",
        "title": "1 volume is not attached to anything",
        "targets": [
          "aws_ebs_volume.leftover"
        ],
        "why": "These volumes are declared but nothing in the configuration references them.",
        "risk": "Detached volumes bill at full provisioned capacity indefinitely and often hold forgotten data.",
        "bestPractice": "Snapshot and delete unattached volumes, and add a lifecycle policy for the snapshots.",
        "impact": "Stops paying for storage that no workload uses."
      }
    ],
    "counts": {
      "critical": 3,
      "high": 2,
      "medium": 4,
      "low": 1
    },
    "grade": {
      "score": 0,
      "letter": "F",
      "color": "#FF637E"
    },
    "summary": {
      "resources": 9,
      "byCategory": {
        "compute": 0,
        "container": 1,
        "storage": 2,
        "database": 2,
        "network": 3,
        "edge": 0,
        "security": 1,
        "identity": 0,
        "integration": 0,
        "observability": 0,
        "other": 0
      },
      "clouds": [
        "aws"
      ]
    }
  }
}
