# Docker / compose security pre-scan (ARION service)

Deterministic scanner for Dockerfile and docker-compose
misconfigurations. No network, no image pulls, no daemon access,
no secrets required — works fully offline.

**Honest scope:** this is a *pre-scan*, not an audit. Files are read
line/indentation-wise — it does not evaluate multi-stage dataflow,
base-image CVEs, or runtime behavior. A FLAG means "this property
deserves human review"; a clean report is not proof an image is safe.

## Coverage

- **Root execution** — `NO-USER` (MEDIUM) when the final stage has no
  `USER` instruction; `USER-ROOT` (MEDIUM) for an explicit
  `USER root`/`0`.
- **Mutable base pins** — `BASE-LATEST` (MEDIUM) for `:latest` or
  untagged bases; `BASE-TAGPIN` (LOW) for tag pins (mutable) vs
  `@sha256:` digests (immutable); `FROM-ARGPIN` (INFO) when the base
  is an ARG variable.
- **Unverified remote fetches** — `PIPE-SHELL` (HIGH) for
  `curl|wget … | sh` pipe-to-shell; `ADD-REMOTE` (MEDIUM) for
  `ADD <url>`; `FETCH-NOCHECKSUM` (MEDIUM) for downloads with no
  checksum/signature verification in the same instruction.
- **Secrets in the build** — `SECRET-IN-ENV` / `SECRET-IN-ARG` (HIGH
  with a literal value, MEDIUM as a bare name) for credential-named
  `ENV`/`ARG` — values land in image metadata and layer history;
  `COPY-ENV` (HIGH) for copying a dotenv file in;
  `SECRET-TO-FILE` (INFO) for credential-looking writes in RUN;
  compose `SECRET-IN-ENV` (HIGH) for literal credential values.
- **Context leakage** — `BROAD-COPY` (LOW) for `COPY .`/`ADD .` —
  .env, .git, and credentials can leak into layers.
- **Compose host-equivalence** — `PRIVILEGED` (HIGH),
  `DOCKER-SOCK` (HIGH, daemon = host root), `CAP-ADMIN` (HIGH for
  `SYS_ADMIN`/`ALL`), `NET-HOST` / `NS-HOST` (MEDIUM).
- **Hygiene** — `CHMOD-777` (MEDIUM), `EXPOSE-SSH` (LOW),
  `SUDO-IN-RUN` (LOW), `PORT-PUBLISH` (INFO), `ENV-FILE` (INFO),
  `IMAGE-LATEST` (LOW), `NO-HEALTHCHECK` (INFO).

## Usage

```
python3 docker_prescan.py <Dockerfile-or-repo-dir> [--json]
python3 docker_prescan.py --selftest     # 16 vectors
```

Stdlib only (Python 3.8+). Exit 0 = no HIGH/MEDIUM findings,
1 = findings, 2 = usage error. Accepts a single file or walks a repo
(skipping `.git`, `node_modules`, `vendor`).

Output is a markdown report (see `sample-report.md`) or JSON with
`--json` for piping into other tooling.

## Validation

- 16 selftest vectors pass (Dockerfile classes + compose fixture).
- Live-validated on real repositories: flagged pipe-to-shell
  installer, literal `POSTGRES_PASSWORD` in a compose file,
  unpinned bases, and missing `USER` — all true positives confirmed
  by reading the flagged lines.

Built by ARION (autonomous agent, human-supervised). Pre-scan output
supports — never replaces — human review.
