created docker security audit playbook

This commit is contained in:
2026-03-22 12:15:33 -07:00
parent 823a995364
commit 2a1b93d8f6
2 changed files with 225 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
containers.local.txt
reports/

View File

@@ -0,0 +1,223 @@
# Playbook: Docker Image Security Audit
Use this playbook to audit Docker images across your environment for vulnerabilities, misconfigurations, secrets, and anything that could compromise the host or network.
When invoked, read `containers.local.txt` in the current working directory and work through each section for every image listed.
---
## How to Use
Tell the AI: _"Use the docker-security-audit playbook"_
The AI will:
1. Read `containers.local.txt` to get the list of images to audit
2. For each image — pull it, run all checks below, and evaluate results
3. For each finding — report CRITICAL, HIGH, MEDIUM, LOW, or INFO
4. Generate a timestamped report file in the `reports/` directory
5. Remove the image from the local host after scanning **unless** it is currently active (`docker ps`)
6. At the end, give an overall environment summary
Do not skip or abbreviate checks. Run every tool listed for every image.
---
## Pre-Flight
Before scanning any images:
- [ ] Confirm `trivy` is installed: `trivy --version`
- [ ] Confirm `docker scout` is available: `docker scout version`
- [ ] Confirm Docker daemon is running: `docker info`
- [ ] Confirm a `reports/` directory exists in the working directory
**AI Action:** Run the above checks. If any tool is missing, stop and tell the user what needs to be installed before continuing. Do not proceed with a partial toolset.
### containers.local.txt Bootstrap
Check if `containers.local.txt` exists in the current working directory.
- **If it does not exist:** Create it with the following content, then stop and instruct the user to populate it before running the audit:
```
# Local Docker image inventory
# Format: image:tag — one per line
# This file is excluded from git. Keep it updated per host.
# Images without a tag will be treated as :latest (flagged as WARN in audit).
```
Tell the user: _"`containers.local.txt` was not found and has been created. Add your image:tag entries (one per line) and re-run the playbook."_
- **If it exists but is empty or contains only comments:** Same as above — stop and prompt the user to add images.
- **If it exists and has valid entries:** Continue to scanning.
---
## Per-Image Procedure
Repeat this entire procedure for **every** `image:tag` entry in `containers.local.txt`.
### Step 1 — Check if Already Active
Run: `docker ps --format '{{.Image}}'`
- If the image is in the active list → mark as **ACTIVE**, skip Step 6 (do not remove)
- If not active → mark as **NOT ACTIVE**, will be removed after scan
### Step 2 — Pull the Image
Run: `docker pull <image:tag>`
- If pull fails → mark as WARN (image may be private, unavailable, or tag deleted) and skip to next image
- Note the image digest and creation date
### Step 3 — CVE Scan (Trivy)
Run: `trivy image --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL --format json <image:tag>`
Report findings grouped by severity:
| Severity | Count | Notable CVEs |
|---|---|---|
| CRITICAL | | |
| HIGH | | |
| MEDIUM | | |
| LOW | | |
| UNKNOWN | | |
- List every CRITICAL and HIGH CVE individually with: CVE ID, affected package, fixed version (if available), and a one-line description of the risk
- Summarise MEDIUM/LOW as counts only unless the user asks for detail
- Flag any CVE with a known public exploit (Trivy marks these with `--ignore-unfixed` info)
### Step 4 — CVE Scan (Docker Scout)
Run: `docker scout cves <image:tag>`
- Cross-reference with Trivy results — note any findings unique to Scout that Trivy missed
- Report new findings in the same severity table format as Step 3
- If Scout and Trivy agree, note "Confirmed by both scanners"
### Step 5 — Extended Checks (Trivy)
Run each of the following and report all findings:
**Secrets scan:**
`trivy image --scanners secret <image:tag>`
- Report any detected secrets: type, file path inside image, line number if available
- Even LOW confidence matches should be reported — flag clearly as low confidence
**Misconfiguration scan:**
`trivy image --scanners misconfig <image:tag>`
- Dockerfile best practice violations
- CIS Docker Benchmark failures
- Report each finding with: check ID, title, severity, description, and remediation
**License scan:**
`trivy image --scanners license --severity UNKNOWN,HIGH <image:tag>`
- Flag any unknown or restrictive licenses (GPL in a closed deployment, etc.)
**SBOM generation:**
`trivy image --format cyclonedx --output reports/sbom-<image-name>-<date>.json <image:tag>`
- Generate and save an SBOM for the image — no pass/fail, this is for records
### Step 6 — Image Cleanup
After all scans are complete for this image:
- If **NOT ACTIVE**: run `docker rmi <image:tag>`
- Confirm removal succeeded
- If removal fails (e.g. stopped container referencing it), note the reason and flag for manual cleanup
- If **ACTIVE**: skip removal, note it in the report
---
## Report Generation
After all images are scanned, generate a single report file:
**Filename:** `reports/docker-audit-<YYYY-MM-DD>.md`
The report must include:
### Report Sections
#### Summary Table
| Image | CRITICAL | HIGH | MEDIUM | LOW | Secrets | Misconfigs | Status | Removed |
|---|---|---|---|---|---|---|---|---|
| image:tag | 0 | 0 | 0 | 0 | 0 | 0 | ACTIVE/NOT ACTIVE | YES/NO/FAILED |
#### Critical & High Findings (Detail)
For every CRITICAL or HIGH CVE across all images:
```
Image: <image:tag>
CVE: CVE-XXXX-XXXXX
Package: <package name and version>
Fixed in: <version> (or "No fix available")
Scanner: Trivy / Docker Scout / Both
Risk: <one-line plain-English description>
```
#### Secrets Detected
For every secret finding:
```
Image: <image:tag>
Type: <e.g. AWS key, generic password, private key>
Confidence: HIGH / MEDIUM / LOW
Path: <file path inside image>
Action: INVESTIGATE / ROTATE IMMEDIATELY
```
#### Misconfigurations
For every misconfiguration finding:
```
Image: <image:tag>
Check: <CIS ID or Trivy check ID>
Title: <short title>
Severity: <severity>
Detail: <description>
Fix: <remediation>
```
#### Cleanup Log
List every image and whether it was removed, skipped (active), or failed to remove.
#### Overall Risk Rating
After all findings:
- **CRITICAL findings present** → Environment status: **AT RISK** — immediate action required
- **HIGH findings only** → Environment status: **ELEVATED** — remediate within 7 days
- **MEDIUM/LOW only** → Environment status: **ACCEPTABLE** — remediate in next maintenance window
- **No findings** → Environment status: **CLEAN**
---
## Severity Reference
| Severity | Action Required |
|---|---|
| CRITICAL | Stop and flag immediately. Do not defer. Notify user before continuing. |
| HIGH | Report in full. User must acknowledge before moving to next image. |
| MEDIUM | Report and continue. Include in final report. |
| LOW | Count only unless user requests detail. |
| INFO | Include in SBOM/records only. |
---
## Notes for the AI
- Never skip an image without documenting why
- Never abbreviate CVE lists for CRITICAL or HIGH findings
- If a scan command fails (not just returns no findings), report the error and the command that failed
- Do not remove an image that appears in `docker ps` output under any circumstances
- If `containers.local.txt` references an image with no tag, assume `:latest` and note it as a WARN (unpinned tag)
- SBOM files are supplemental — save them but do not report their contents unless the user asks