proofctl 0.4.2__tar.gz → 0.4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {proofctl-0.4.2/proofctl.egg-info → proofctl-0.4.3}/PKG-INFO +5 -5
  2. {proofctl-0.4.2 → proofctl-0.4.3}/README.md +4 -4
  3. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/terraform.py +179 -0
  4. {proofctl-0.4.2 → proofctl-0.4.3/proofctl.egg-info}/PKG-INFO +5 -5
  5. {proofctl-0.4.2 → proofctl-0.4.3}/pyproject.toml +1 -1
  6. {proofctl-0.4.2 → proofctl-0.4.3}/LICENSE +0 -0
  7. {proofctl-0.4.2 → proofctl-0.4.3}/MANIFEST.in +0 -0
  8. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/__init__.py +0 -0
  9. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/_globmatch.py +0 -0
  10. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/baseline.py +0 -0
  11. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/__init__.py +0 -0
  12. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/base.py +0 -0
  13. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/dockerfile.py +0 -0
  14. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/hcl_utils.py +0 -0
  15. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/imports.py +0 -0
  16. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/leakage.py +0 -0
  17. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/llm_integration.py +0 -0
  18. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/placeholders.py +0 -0
  19. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/quality.py +0 -0
  20. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/secrets.py +0 -0
  21. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/security.py +0 -0
  22. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/shell_checker.py +0 -0
  23. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/terragrunt.py +0 -0
  24. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/variants.py +0 -0
  25. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/checkers/yaml_checker.py +0 -0
  26. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/cli.py +0 -0
  27. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/config.py +0 -0
  28. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/engine.py +0 -0
  29. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/fixer.py +0 -0
  30. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/models.py +0 -0
  31. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/registry.py +0 -0
  32. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/reporters/__init__.py +0 -0
  33. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/reporters/html_reporter.py +0 -0
  34. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/reporters/json_reporter.py +0 -0
  35. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl/reporters/terminal.py +0 -0
  36. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl.egg-info/SOURCES.txt +0 -0
  37. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl.egg-info/dependency_links.txt +0 -0
  38. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl.egg-info/entry_points.txt +0 -0
  39. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl.egg-info/requires.txt +0 -0
  40. {proofctl-0.4.2 → proofctl-0.4.3}/proofctl.egg-info/top_level.txt +0 -0
  41. {proofctl-0.4.2 → proofctl-0.4.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proofctl
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: Zero-dependency linter for Python, Terraform, Dockerfiles, Kubernetes, and GitHub Actions — catches AI slop and security misconfigurations pre-commit
5
5
  Author-email: Kolawolu Odunola <kolawolu.o@gmail.com>
6
6
  License: MIT
@@ -28,7 +28,7 @@ Dynamic: license-file
28
28
 
29
29
  # proofctl
30
30
 
31
- A linter built for the DevOps stack — Python, Terraform, Kubernetes, Helm, Dockerfiles, GitHub Actions, Shell — that catches the specific kinds of mistakes AI coding tools introduce. **264 rules**, zero dependencies, runs in under a second.
31
+ A linter built for the DevOps stack — Python, Terraform, Kubernetes, Helm, Dockerfiles, GitHub Actions, Shell — that catches the specific kinds of mistakes AI coding tools introduce. **267 rules**, zero dependencies, runs in under a second.
32
32
 
33
33
  ```
34
34
  proofctl check .
@@ -165,7 +165,7 @@ git commit -m "chore: add proofctl baseline"
165
165
 
166
166
  ## Rules
167
167
 
168
- 264 rules across 14 families. Run `proofctl rules` after install to enumerate.
168
+ 267 rules across 14 families. Run `proofctl rules` after install to enumerate.
169
169
 
170
170
  | Family | Count | What it covers |
171
171
  |---|---|---|
@@ -173,9 +173,9 @@ git commit -m "chore: add proofctl baseline"
173
173
  | Python — Security (`S`) | 24 | OWASP Top-10 + CWE coverage: SQLi, command injection, weak crypto, JWT bypass, path traversal, XSS, SSRF, file upload, CSRF, missing authz, XPath injection, open redirect, TLS bypass |
174
174
  | Secrets (`SECRET`) | 13 | AWS / GCP / GitHub / Slack / Stripe / private keys / JWTs / hardcoded passwords / K8s Secret YAML / connection strings with embedded creds |
175
175
  | Python — Other | 12 | Placeholders, leakage (cross-language idioms, PII), import hallucination, method complexity, variant detection, LLM guardrails (OWASP LLM Top-10) |
176
- | Terraform — General + AI (`TF-T`, `TF-AI`) | 26 | required_version, sensitive outputs, IAM wildcards, mutable git refs, deprecated resources, AWS-region-in-GCP, placeholder values |
176
+ | Terraform — General + AI (`TF-T`, `TF-AI`) | 28 | required_version, sensitive outputs, IAM wildcards, mutable git refs, deprecated resources, AWS-region-in-GCP, placeholder values, image-family pinning, sensitive vars in VM metadata |
177
177
  | Terraform — AWS (`TF-A`) | 40 | EC2 IMDSv2, S3 public-access-block, EBS encryption, VPC flow logs, KMS rotation, RDS hardening, SG / NACL / EKS / DynamoDB / ElastiCache / CloudTrail / IAM |
178
- | Terraform — GCP (`TF-G`) | 50 | GKE hardening, GCS public-access prevention, IAM roles, KMS rotation, Cloud Function/Run public, BigQuery, Pub/Sub CMEK, Cloud SQL, firewall ingress |
178
+ | Terraform — GCP (`TF-G`) | 51 | GKE hardening, GCS public-access prevention, IAM roles, KMS rotation, Cloud Function/Run public, BigQuery, Pub/Sub CMEK, Cloud SQL, firewall ingress, compute access scopes |
179
179
  | Terraform — Azure (`TF-AZ`) | 14 | Storage public blob, SQL public network, AKS RBAC, Key Vault purge protection, NSG SSH/RDP, managed disk CMK |
180
180
  | Terraform — Mechanics + Lifecycle (`TF-M`, `TF-V`) | 12 | SG inline mixing, `force_destroy`, mutable module refs, lifecycle antipatterns |
181
181
  | Terragrunt (`TG`) | 6 | HCL inputs, mock_outputs, remote state encryption |
@@ -1,6 +1,6 @@
1
1
  # proofctl
2
2
 
3
- A linter built for the DevOps stack — Python, Terraform, Kubernetes, Helm, Dockerfiles, GitHub Actions, Shell — that catches the specific kinds of mistakes AI coding tools introduce. **264 rules**, zero dependencies, runs in under a second.
3
+ A linter built for the DevOps stack — Python, Terraform, Kubernetes, Helm, Dockerfiles, GitHub Actions, Shell — that catches the specific kinds of mistakes AI coding tools introduce. **267 rules**, zero dependencies, runs in under a second.
4
4
 
5
5
  ```
6
6
  proofctl check .
@@ -137,7 +137,7 @@ git commit -m "chore: add proofctl baseline"
137
137
 
138
138
  ## Rules
139
139
 
140
- 264 rules across 14 families. Run `proofctl rules` after install to enumerate.
140
+ 267 rules across 14 families. Run `proofctl rules` after install to enumerate.
141
141
 
142
142
  | Family | Count | What it covers |
143
143
  |---|---|---|
@@ -145,9 +145,9 @@ git commit -m "chore: add proofctl baseline"
145
145
  | Python — Security (`S`) | 24 | OWASP Top-10 + CWE coverage: SQLi, command injection, weak crypto, JWT bypass, path traversal, XSS, SSRF, file upload, CSRF, missing authz, XPath injection, open redirect, TLS bypass |
146
146
  | Secrets (`SECRET`) | 13 | AWS / GCP / GitHub / Slack / Stripe / private keys / JWTs / hardcoded passwords / K8s Secret YAML / connection strings with embedded creds |
147
147
  | Python — Other | 12 | Placeholders, leakage (cross-language idioms, PII), import hallucination, method complexity, variant detection, LLM guardrails (OWASP LLM Top-10) |
148
- | Terraform — General + AI (`TF-T`, `TF-AI`) | 26 | required_version, sensitive outputs, IAM wildcards, mutable git refs, deprecated resources, AWS-region-in-GCP, placeholder values |
148
+ | Terraform — General + AI (`TF-T`, `TF-AI`) | 28 | required_version, sensitive outputs, IAM wildcards, mutable git refs, deprecated resources, AWS-region-in-GCP, placeholder values, image-family pinning, sensitive vars in VM metadata |
149
149
  | Terraform — AWS (`TF-A`) | 40 | EC2 IMDSv2, S3 public-access-block, EBS encryption, VPC flow logs, KMS rotation, RDS hardening, SG / NACL / EKS / DynamoDB / ElastiCache / CloudTrail / IAM |
150
- | Terraform — GCP (`TF-G`) | 50 | GKE hardening, GCS public-access prevention, IAM roles, KMS rotation, Cloud Function/Run public, BigQuery, Pub/Sub CMEK, Cloud SQL, firewall ingress |
150
+ | Terraform — GCP (`TF-G`) | 51 | GKE hardening, GCS public-access prevention, IAM roles, KMS rotation, Cloud Function/Run public, BigQuery, Pub/Sub CMEK, Cloud SQL, firewall ingress, compute access scopes |
151
151
  | Terraform — Azure (`TF-AZ`) | 14 | Storage public blob, SQL public network, AKS RBAC, Key Vault purge protection, NSG SSH/RDP, managed disk CMK |
152
152
  | Terraform — Mechanics + Lifecycle (`TF-M`, `TF-V`) | 12 | SG inline mixing, `force_destroy`, mutable module refs, lifecycle antipatterns |
153
153
  | Terragrunt (`TG`) | 6 | HCL inputs, mock_outputs, remote state encryption |
@@ -294,6 +294,7 @@ class TerraformChecker(HclFileChecker):
294
294
  out += self._g044(path, blocks)
295
295
  out += self._g045(path, blocks)
296
296
  out += self._g046(path, blocks)
297
+ out += self._g047(path, blocks)
297
298
 
298
299
  # Group AZ — Azure
299
300
  out += self._az001(path, blocks)
@@ -327,6 +328,8 @@ class TerraformChecker(HclFileChecker):
327
328
  out += self._ai009(path, lines)
328
329
  out += self._ai010(path, lines)
329
330
  out += self._ai011(path, lines)
331
+ out += self._ai012(path, blocks)
332
+ out += self._ai013(path, blocks)
330
333
 
331
334
  return out
332
335
 
@@ -2935,6 +2938,36 @@ class TerraformChecker(HclFileChecker):
2935
2938
  break
2936
2939
  return out
2937
2940
 
2941
+ def _g047(self, path: Path, blocks: list[HclBlock]) -> list[Finding]:
2942
+ """G-047 — Compute instance with `cloud-platform` access scope.
2943
+
2944
+ Access scopes are a coarse, IAM-bypassing layer on top of service-account
2945
+ permissions. `cloud-platform` grants the metadata server permission to
2946
+ mint tokens for every GCP API — so any role the SA ever acquires becomes
2947
+ immediately usable from the VM. Best practice: rely on IAM only, and
2948
+ narrow the scope to `cloud-platform.read-only` or use the default
2949
+ scopes set with explicit IAM roles.
2950
+ """
2951
+ out = []
2952
+ for b in blocks:
2953
+ if b.kind != "resource" or b.label1 != "google_compute_instance":
2954
+ continue
2955
+ for sa in b.nested("service_account"):
2956
+ # Match "cloud-platform" exactly inside the scopes list — not
2957
+ # cloud-platform.read-only or other narrower scopes.
2958
+ if sa.contains(r'"cloud-platform"'):
2959
+ out.append(self._f(
2960
+ path, sa.attr_line("scopes") or sa.start_line,
2961
+ "PROOFCTL-TF-G047", "Compute instance with cloud-platform scope",
2962
+ Severity.WARNING,
2963
+ f'google_compute_instance "{b.label2}" has access scope "cloud-platform" — broadest possible API access',
2964
+ hint='Use narrower scopes (e.g. "cloud-platform.read-only") or omit and rely on IAM bindings on the service account.',
2965
+ authority="GCP Compute Engine — Access scopes vs IAM",
2966
+ docs_url="https://cloud.google.com/compute/docs/access/service-accounts#scopes_best_practice",
2967
+ ))
2968
+ break
2969
+ return out
2970
+
2938
2971
  # ════════════════════════════════════════════════════════════════════════
2939
2972
  # Group AZ — Azure data-exfiltration rules (extended)
2940
2973
  # ════════════════════════════════════════════════════════════════════════
@@ -3328,6 +3361,152 @@ class TerraformChecker(HclFileChecker):
3328
3361
  ))
3329
3362
  return out
3330
3363
 
3364
+ # GCE boot disk that references an image *family* rather than a specific
3365
+ # image is the GCP equivalent of `:latest` — Google promotes new images
3366
+ # into a family on its own schedule. Any apply that triggers VM rebuild
3367
+ # picks up whatever's current that day. Sneaky drift / surprise OS upgrade
3368
+ # vector that AI tools default to because the canonical examples use it.
3369
+ _IMAGE_FAMILY_RE = re.compile(
3370
+ r'image\s*=\s*"[^"]*?/images/family/[^"]+"',
3371
+ )
3372
+
3373
+ def _ai012(self, path: Path, blocks: list[HclBlock]) -> list[Finding]:
3374
+ """AI-012 — GCE boot disk references an image *family* (mutable)."""
3375
+ out = []
3376
+ for b in blocks:
3377
+ if b.kind != "resource" or b.label1 != "google_compute_instance":
3378
+ continue
3379
+ for bd in b.nested("boot_disk"):
3380
+ # `image` can live either directly on boot_disk or inside
3381
+ # the nested initialize_params block.
3382
+ targets = [bd] + bd.nested("initialize_params")
3383
+ for t in targets:
3384
+ line = t.any_line_matches(self._IMAGE_FAMILY_RE.pattern)
3385
+ if line is not None:
3386
+ out.append(self._f(
3387
+ path, line,
3388
+ "PROOFCTL-TF-AI-012",
3389
+ "GCE boot disk uses image family (mutable)",
3390
+ Severity.WARNING,
3391
+ f'google_compute_instance "{b.label2}" references an image family — Google promotes new images into the family at any time',
3392
+ hint="Pin to a specific image name (e.g. ubuntu-2404-amd64-20251101) or set lifecycle { ignore_changes = [boot_disk[0].initialize_params[0].image] } to opt out of rebuilds.",
3393
+ authority="GCP Compute Engine — Image families",
3394
+ docs_url="https://cloud.google.com/compute/docs/images/image-families-best-practices",
3395
+ ))
3396
+ break # one finding per boot_disk is enough
3397
+ return out
3398
+
3399
+ # Variables likely to hold credential material — used by AI-013 to decide
3400
+ # which `var.X` references are dangerous to embed in compute metadata.
3401
+ # Aligns with the SECRET-007 name set so engineers don't have to learn
3402
+ # two parallel taxonomies.
3403
+ _SENSITIVE_VAR_NAME_RE = re.compile(
3404
+ r"\bvar\.((?:[a-zA-Z0-9_]*_)?"
3405
+ r"(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|"
3406
+ r"private[_-]?key|client[_-]?secret|encryption[_-]?key|auth[_-]?token|"
3407
+ r"bearer[_-]?token|jwt|credential|tunnel[_-]?token)"
3408
+ r"[a-zA-Z0-9_]*)\b",
3409
+ re.IGNORECASE,
3410
+ )
3411
+
3412
+ @staticmethod
3413
+ def _line_range_of_attr(
3414
+ block: HclBlock, attr_name: str
3415
+ ) -> tuple[int, int] | None:
3416
+ """Find (start_idx, end_idx) into block.raw_lines that span the attribute
3417
+ ``attr_name = <value>`` including any continuation lines opened by
3418
+ parentheses or brackets.
3419
+
3420
+ Returns indices relative to ``block.raw_lines`` (0-based), inclusive of
3421
+ the closing bracket / paren line. Returns None if the attribute is not
3422
+ present.
3423
+ """
3424
+ head = re.compile(rf"^\s*{re.escape(attr_name)}\s*=\s*(.*)$")
3425
+ for i, line in enumerate(block.raw_lines):
3426
+ m = head.match(line)
3427
+ if not m:
3428
+ continue
3429
+ rest = m.group(1)
3430
+ depth = rest.count("(") + rest.count("[") + rest.count("{")
3431
+ depth -= rest.count(")") + rest.count("]") + rest.count("}")
3432
+ if depth <= 0:
3433
+ return (i, i)
3434
+ j = i + 1
3435
+ while j < len(block.raw_lines) and depth > 0:
3436
+ ln = block.raw_lines[j]
3437
+ depth += ln.count("(") + ln.count("[") + ln.count("{")
3438
+ depth -= ln.count(")") + ln.count("]") + ln.count("}")
3439
+ j += 1
3440
+ return (i, j - 1)
3441
+ return None
3442
+
3443
+ def _ai013(self, path: Path, blocks: list[HclBlock]) -> list[Finding]:
3444
+ """AI-013 — Sensitive variable interpolated into compute metadata.
3445
+
3446
+ Pattern: `var.<secret-shaped-name>` appears inside ``metadata_startup_script``
3447
+ or any nested ``metadata { ... }`` block on a ``google_compute_instance``
3448
+ resource.
3449
+
3450
+ Risk: anything that ends up in VM metadata is readable by any caller
3451
+ with ``compute.instances.get`` and is written to plan / state. The
3452
+ Cloudflare-tunnel-in-startup-script pattern is the canonical AI-slop
3453
+ instance.
3454
+ """
3455
+ out = []
3456
+ seen: set[tuple[Path, int]] = set()
3457
+
3458
+ def _emit(b: HclBlock, line: int, var_name: str, surface: str) -> None:
3459
+ key = (path, line)
3460
+ if key in seen:
3461
+ return
3462
+ seen.add(key)
3463
+ out.append(self._f(
3464
+ path, line,
3465
+ "PROOFCTL-TF-AI-013",
3466
+ "Sensitive variable in compute metadata",
3467
+ Severity.ERROR,
3468
+ f'google_compute_instance "{b.label2}" passes var.{var_name} into {surface} — secret will be readable from VM metadata and visible in plan/state',
3469
+ hint=(
3470
+ "Mount the secret from Secret Manager inside the VM at runtime "
3471
+ "(google_secret_manager_secret_iam_member + a startup script that "
3472
+ "calls `gcloud secrets versions access`). Do not bake the value into metadata."
3473
+ ),
3474
+ authority="CIS GCP Benchmark 4.6 / OWASP A02 Cryptographic Failures",
3475
+ docs_url="https://cloud.google.com/compute/docs/metadata/overview#metadata_security_considerations",
3476
+ ))
3477
+
3478
+ for b in blocks:
3479
+ if b.kind != "resource" or b.label1 != "google_compute_instance":
3480
+ continue
3481
+ # 1. Scan metadata_startup_script line range.
3482
+ rng = self._line_range_of_attr(b, "metadata_startup_script")
3483
+ if rng is not None:
3484
+ lo, hi = rng
3485
+ for offset in range(lo, hi + 1):
3486
+ line_text = b.raw_lines[offset]
3487
+ m = self._SENSITIVE_VAR_NAME_RE.search(line_text)
3488
+ if m:
3489
+ _emit(b, b.start_line + offset, m.group(1),
3490
+ "metadata_startup_script")
3491
+ # 2. Scan nested metadata { ... } blocks (HCL block form).
3492
+ for md in b.nested("metadata"):
3493
+ for offset, line_text in enumerate(md.raw_lines):
3494
+ m = self._SENSITIVE_VAR_NAME_RE.search(line_text)
3495
+ if m:
3496
+ _emit(b, md.start_line + offset, m.group(1),
3497
+ "metadata block")
3498
+ # 3. Scan metadata = { ... } attribute (HCL object-attribute form).
3499
+ rng = self._line_range_of_attr(b, "metadata")
3500
+ if rng is not None:
3501
+ lo, hi = rng
3502
+ for offset in range(lo, hi + 1):
3503
+ line_text = b.raw_lines[offset]
3504
+ m = self._SENSITIVE_VAR_NAME_RE.search(line_text)
3505
+ if m:
3506
+ _emit(b, b.start_line + offset, m.group(1),
3507
+ "metadata block")
3508
+ return out
3509
+
3331
3510
 
3332
3511
  # ── Directory-level checker (cross-file rules) ───────────────────────────────
3333
3512
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proofctl
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: Zero-dependency linter for Python, Terraform, Dockerfiles, Kubernetes, and GitHub Actions — catches AI slop and security misconfigurations pre-commit
5
5
  Author-email: Kolawolu Odunola <kolawolu.o@gmail.com>
6
6
  License: MIT
@@ -28,7 +28,7 @@ Dynamic: license-file
28
28
 
29
29
  # proofctl
30
30
 
31
- A linter built for the DevOps stack — Python, Terraform, Kubernetes, Helm, Dockerfiles, GitHub Actions, Shell — that catches the specific kinds of mistakes AI coding tools introduce. **264 rules**, zero dependencies, runs in under a second.
31
+ A linter built for the DevOps stack — Python, Terraform, Kubernetes, Helm, Dockerfiles, GitHub Actions, Shell — that catches the specific kinds of mistakes AI coding tools introduce. **267 rules**, zero dependencies, runs in under a second.
32
32
 
33
33
  ```
34
34
  proofctl check .
@@ -165,7 +165,7 @@ git commit -m "chore: add proofctl baseline"
165
165
 
166
166
  ## Rules
167
167
 
168
- 264 rules across 14 families. Run `proofctl rules` after install to enumerate.
168
+ 267 rules across 14 families. Run `proofctl rules` after install to enumerate.
169
169
 
170
170
  | Family | Count | What it covers |
171
171
  |---|---|---|
@@ -173,9 +173,9 @@ git commit -m "chore: add proofctl baseline"
173
173
  | Python — Security (`S`) | 24 | OWASP Top-10 + CWE coverage: SQLi, command injection, weak crypto, JWT bypass, path traversal, XSS, SSRF, file upload, CSRF, missing authz, XPath injection, open redirect, TLS bypass |
174
174
  | Secrets (`SECRET`) | 13 | AWS / GCP / GitHub / Slack / Stripe / private keys / JWTs / hardcoded passwords / K8s Secret YAML / connection strings with embedded creds |
175
175
  | Python — Other | 12 | Placeholders, leakage (cross-language idioms, PII), import hallucination, method complexity, variant detection, LLM guardrails (OWASP LLM Top-10) |
176
- | Terraform — General + AI (`TF-T`, `TF-AI`) | 26 | required_version, sensitive outputs, IAM wildcards, mutable git refs, deprecated resources, AWS-region-in-GCP, placeholder values |
176
+ | Terraform — General + AI (`TF-T`, `TF-AI`) | 28 | required_version, sensitive outputs, IAM wildcards, mutable git refs, deprecated resources, AWS-region-in-GCP, placeholder values, image-family pinning, sensitive vars in VM metadata |
177
177
  | Terraform — AWS (`TF-A`) | 40 | EC2 IMDSv2, S3 public-access-block, EBS encryption, VPC flow logs, KMS rotation, RDS hardening, SG / NACL / EKS / DynamoDB / ElastiCache / CloudTrail / IAM |
178
- | Terraform — GCP (`TF-G`) | 50 | GKE hardening, GCS public-access prevention, IAM roles, KMS rotation, Cloud Function/Run public, BigQuery, Pub/Sub CMEK, Cloud SQL, firewall ingress |
178
+ | Terraform — GCP (`TF-G`) | 51 | GKE hardening, GCS public-access prevention, IAM roles, KMS rotation, Cloud Function/Run public, BigQuery, Pub/Sub CMEK, Cloud SQL, firewall ingress, compute access scopes |
179
179
  | Terraform — Azure (`TF-AZ`) | 14 | Storage public blob, SQL public network, AKS RBAC, Key Vault purge protection, NSG SSH/RDP, managed disk CMK |
180
180
  | Terraform — Mechanics + Lifecycle (`TF-M`, `TF-V`) | 12 | SG inline mixing, `force_destroy`, mutable module refs, lifecycle antipatterns |
181
181
  | Terragrunt (`TG`) | 6 | HCL inputs, mock_outputs, remote state encryption |
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "proofctl"
7
- version = "0.4.2"
7
+ version = "0.4.3"
8
8
  description = "Zero-dependency linter for Python, Terraform, Dockerfiles, Kubernetes, and GitHub Actions — catches AI slop and security misconfigurations pre-commit"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes