TL;DR

Why We Did This

We built Misconfig Index to give any public GitHub repo an IaC security score — the kind of quick signal that CI/CD pipelines and security reviews need. Before we started telling people their repos had problems, we wanted to understand the baseline: what does the broader IaC ecosystem actually look like?

We selected 92 public repos representing a realistic cross-section — official cloud provider modules, popular community modules, real-world applications, GitOps tooling, and Helm chart repositories. Then we ran every one of them through the scanner locally, with no rate limits and no cherry-picking.

Methodology

All repos were scanned using the Misconfig Index local scanner (git clone + static analysis, no network calls). The scanner detects misconfigurations across Terraform HCL, Kubernetes YAML, CloudFormation JSON/YAML, and Dockerfiles. Variable blocks and auto-generated wrapper modules are excluded to avoid false positives on module input declarations. Provider SDK repos (terraform-provider-*) and the Kubernetes monorepo were excluded since they contain test fixtures rather than deployed infrastructure. Six educational repos (Udemy courses, O'Reilly book companion code, official tutorial examples) are reported separately — they intentionally demonstrate misconfigured patterns for teaching purposes.

Scores run 0–100. Grades map A (90–100) → F (0–39).

The Distribution Is Bimodal — and That's the Story

The average score across all 92 repos is 87.9/100. The median is 98/100.

Those two numbers tell you everything: most repos are clean, but a handful are dragging the average down hard.

GradeReposPct
A (90–100)6368%
B (80–89)1112%
C (70–79)910%
D (40–69)67%
F (0–39)33%

The 68% getting an A aren't squeaking by — most score 95–100. The repos in the D–F range have deep, systemic issues: hundreds of findings concentrated in a small number of rule categories. This isn't a bell curve. It's two clusters with a gap in between.

Finding #1: CloudFormation Is Surprisingly Clean

We expected CloudFormation to perform roughly in line with Terraform — same declarative config, same kind of AWS-specific rules. It didn't come close.

IaC TypeReposAvg ScoreTotal FindingsF Grades
CloudFormation9100.010
Mixed (TF+K8s+Docker)597.4330
Dockerfile993.01070
Terraform4486.34142
Kubernetes2582.41,2071

Every single CloudFormation repo scored 100/100. The nine repos generated exactly one finding between them — a single resource in awslabs/aws-cloudformation-templates. (Nine repos is a thin sample — we'd want 30+ before drawing strong conclusions about CFN as a format; treat this as a signal worth investigating, not a verdict.)

Our hypothesis: CloudFormation's declarative JSON/YAML format, combined with AWS's conservative defaults and extensive schema validation at deploy time, pushes misconfiguration issues to the surface earlier than Terraform or Kubernetes. The friction of writing JSON keeps configs simple. Whether that's a feature or a limitation is a separate debate.

Finding #2: Kubernetes Has a Security Problem

Kubernetes repos represent 27% of our dataset but account for 68% of all findings (1,207 out of 1,762). The average Kubernetes repo score is 82.4 — seven points lower than Terraform, fifteen points lower than Dockerfile repos.

The finding distribution is concentrated: a small number of Helm chart repositories (particularly helm/charts, the officially deprecated archive with 287 findings, and bitnami/charts with 201) drove the majority of the volume. But even excluding those, Kubernetes repos consistently had more findings per repo than any other type.

What's driving it? The Kubernetes runtime security model — resource limits, security contexts, privileged mode, host namespaces, read-only filesystems — offers a lot of knobs. Most repos aren't turning them.

The Top 10 Misconfigurations

These are the rules that fired most often across all 92 repos, by total hit count and percentage of repos affected.

#MisconfigurationHitsRepos Affected
1No CPU/memory resource limits47627%
2Container image uses :latest tag37526%
3Container runs as root (UID 0)1789%
4Security group open to 0.0.0.0/016218%
5IAM wildcard resource (*)11910%
6Writable root filesystem11011%
7Privileged container mode10914%
8hostNetwork or hostPID enabled10713%
9Security group allows all traffic (-1)6313%
10IAM wildcard resource (HCL policy)284%

Six of the top 10 are Kubernetes-specific. The two Terraform networking issues (#4 and #9) are the most commonly flagged non-Kubernetes problems.

The top two aren't exotic

Rules 1 and 2 — missing resource limits and :latest image tags — are the unglamorous basics. They're not zero-days. They won't get your name on a CVE. But missing resource limits means one noisy neighbour can starve your entire node, and :latest means your deployments are non-reproducible and your container could silently change under you.

Combined, these two rules account for 851 findings — nearly half the total — across a quarter of all repos.

The networking gap

0.0.0.0/0 in a security group, or a group that allows all traffic with protocol -1, is the Terraform equivalent of chmod 777. It showed up in 18% of repos, almost entirely in Terraform. The specific patterns we saw: egress rules that open all outbound traffic (the default "it works, ship it" pattern) and ingress rules left open from debugging that never got locked down.

IAM wildcards — a real finding in official code

resources = ["*"] in an IAM policy definition appeared in 10% of repos. Some of these are legitimate — certain AWS actions (like cloudwatch:PutMetricData) genuinely have no resource-level restriction. But several were broad admin-style policies attached to service roles. The terraform-aws-modules/terraform-aws-iam module scored F (5/100) specifically because it ships pre-built policies with wildcard resources — a known design trade-off that users should be aware of when adopting those modules.

Finding #3: The Security Category That Consistently Fails

Looking at how repos score by finding category:

CategoryAvg ScoreRepos with Findings
Networking76.720 repos
Identity/IAM80.913 repos
Workload83.232 repos
Storage85.24 repos
Image96.126 repos

Networking is the weakest category — 20 repos had networking findings, and their average networking score was 76.7. Image security (base image hygiene) is the strongest, averaging 96.1.

The gap between image hygiene and networking security is striking. Teams are being deliberate about base images but sloppy about ingress/egress rules.

The Education Gap

Six repos in our dataset are explicitly educational — Udemy courses, O'Reilly book companion code, and official tutorial collections. We analyzed them but kept them out of the trend numbers since they intentionally demonstrate broken patterns for teaching purposes.

ScoreRepoType
F/0 (123 findings)wardviaene/terraform-courseUdemy course
D/45 (97 findings)kubernetes/examplesOfficial K8s tutorial
D/57 (30 findings)futurice/terraform-examplesExample patterns
D/58 (63 findings)ContainerSolutions/kubernetes-examplesK8s tutorial
D/59 (39 findings)brikis98/terraform-up-and-running-codeTerraform: Up & Running code
C/66 (48 findings)wardviaene/kubernetes-courseUdemy course

The course repos score low because they walk through progressively building out infrastructure — including intentionally insecure configs that get fixed by the end of the chapter. The takeaway isn't that the courses are bad. It's that if you're copying config from a tutorial into production without audit, that's the risk vector.

What This Means for Your Repo

Based on the data, the highest-value checks to run on any IaC codebase:

  1. Set resource limits on every container. CPU and memory limits should be mandatory in any production Kubernetes config. They're absent in 27% of repos in our dataset.
  2. Pin your image tags. Replace :latest with a specific digest or semver tag. This is table stakes for reproducible deployments.
  3. Audit your security groups for 0.0.0.0/0. Every open ingress rule should have a documented reason. Egress is lower risk but 0.0.0.0/0 all-traffic egress (-1) rules should also be reviewed.
  4. Scope your IAM policies. Resource: "*" on an action that supports resource-level permissions is unnecessary and a privilege escalation vector.
  5. Check your security contexts. runAsRoot, privileged: true, hostNetwork: true — each one is a potential container escape. If you don't need it, remove it.

Try It on Your Own Repo

Every score in this post was generated by the same scanner available at misconfig.dev. Paste your public GitHub repo URL and get a score in under a minute.

The CLI is also available for CI integration:

pip install misconfig-index
misconfig scan --path ./infra

If you want to run the same bulk analysis we ran here, the scanner, repo list, and analysis scripts are all in the misconfig-index GitHub repo.

Scanned March 2026. 92 repos, 1,762 findings, one very clean CloudFormation dataset.