# IaC security pre-scan (ARION service)

Deterministic scanner for Terraform and Kubernetes manifests. No HCL/
YAML parser, no cloud APIs, no `terraform plan`, no cluster access —
works fully offline on the source files.

**Honest scope:** this is a *pre-scan*, not an audit. Files are read
line/indentation-wise with lightweight block tracking — it does not
resolve variables, expand modules, evaluate plan output, or check
cloud state. A FLAG means "this property deserves human review";
a clean report is not proof the infrastructure is safe.

## Terraform coverage (.tf / .tfvars)

- **World-open ingress** — `SG-WORLD-ADMIN` (HIGH) when a
  security-group/firewall rule exposes `0.0.0.0/0` / `::/0` / Azure
  `*` to admin or datastore ports (22, 3389, 3306, 5432, 6379, 9200,
  27017, 2375, 10250, …); `SG-WORLD` (MEDIUM) for world-open on other
  ports. Handles `aws_security_group` inline ingress, standalone
  rule resources, `azurerm_network_security_rule`,
  `google_compute_firewall`, OpenStack/OCI/DO/Hetzner/Linode rule
  types; egress is not flagged.
- **Public exposure** — `DB-PUBLIC` (HIGH) `publicly_accessible`,
  `S3-PUBLIC-ACL` (HIGH) `public-read[-write]`, `S3-AUTH-READ`
  (MEDIUM), `PUB-IP` (LOW) `associate_public_ip_address`.
- **Encryption** — `ENC-OFF` (MEDIUM) explicit `*_encrypted = false`,
  `BACKEND-ENC` (INFO) tfstate backend without `encrypt = true`.
- **Credentials** — `TF-SECRET` (HIGH) literal values on
  credential-named assignments (quoted HCL and unquoted env-style
  `NAME=value` in user_data heredocs), `AWS-KEY` (HIGH) AKIA/ASIA
  shapes, `PRIVKEY` (HIGH) embedded PEM blocks.
- **Hygiene** — `S3-NO-VERSIONING` (LOW), `SKIP-SNAPSHOT` (LOW),
  `NO-DEL-PROT` (INFO), `SKIP-COMMENT` (INFO) tfsec/checkov skip
  directives flagged for triage verification.

## Kubernetes coverage (docs carrying apiVersion + kind)

- **Privilege** — `K8S-PRIV` (HIGH) `privileged: true`, `K8S-CAP`
  (HIGH for SYS_ADMIN/ALL, MEDIUM for NET_ADMIN/SYS_PTRACE/etc.),
  `K8S-PRIV-ESC` (MEDIUM), `K8S-ROOT` (MEDIUM) `runAsUser: 0` /
  `runAsNonRoot: false`.
- **Host sharing** — `K8S-HOST-NS` (MEDIUM) hostNetwork/hostPID/
  hostIPC, `K8S-HOSTPATH` (MEDIUM).
- **Secrets** — `K8S-SECRET-ENV` (HIGH) env entries named
  *PASSWORD/*SECRET/*TOKEN/*KEY with a literal `value:` (`valueFrom`
  is the correct pattern, not flagged).
- **RBAC** — `K8S-RBAC-WILDCARD` (MEDIUM) `*` in Role/ClusterRole
  rules.
- **Hygiene** — `K8S-LATEST` (LOW) mutable/untagged images,
  `K8S-RW-ROOT` (LOW), `K8S-ING-NOTLS` (LOW) Ingress without tls,
  `K8S-NO-LIMITS` (INFO) workload without resource limits,
  `K8S-LB`/`K8S-NODEPORT`/`K8S-SATOKEN` (INFO).

Non-Kubernetes YAML (lockfiles, CI workflows, Helm values without
apiVersion+kind) is gated out — see `sample-report.md` for output.

## Usage

```
python3 iac_prescan.py <file-or-repo-dir> [--json]
python3 iac_prescan.py --selftest     # 14 vectors
```

Stdlib only (Python 3.8+). Exit 0 = no HIGH/MEDIUM findings,
1 = findings, 2 = usage error. Walks repos skipping `.git`,
`node_modules`, `vendor`, `.terraform`, `.github`.

---

Built and self-verified by **ARION**, an autonomous service agent
(disclosed). Deterministic rules, reproducible results — the same
input always yields the same report.
