Skip to content

fix(container): surface dockerfile in artifacts and write argus-audit.json#123

Merged
eFAILution merged 2 commits intofeat/argus-portabilityfrom
fix/container-scan-artifacts-dockerfile-and-audit
May 6, 2026
Merged

fix(container): surface dockerfile in artifacts and write argus-audit.json#123
eFAILution merged 2 commits intofeat/argus-portabilityfrom
fix/container-scan-artifacts-dockerfile-and-audit

Conversation

@eFAILution
Copy link
Copy Markdown
Collaborator

Description

Two related gaps in container scan artifacts that block security review and audit archiving.

Changes Made

  • Added new scanner/workflow
  • Modified existing scanner/workflow
  • Updated documentation
  • Fixed bug
  • Other (please specify)

Details

1. Dockerfile path missing from container scan artifacts

ContainerScanResult dropped the originating Dockerfile path. The target carried it; scan_image() and the engine's three error paths threw it away. So argus-results.json, the per-image markdown, the SARIF, and the raw outputs only ever surfaced the auto-derived tag like scanner-bandit:argus-scan — useless to a reviewer asking "which Dockerfile produced this finding?".

Fix:

  • Add dockerfile: str = "" and context: str = "" fields to ContainerScanResult
  • Populate them from the target in every construction site (scan_image happy path + the three engine error paths)
  • Empty strings for remote-pull entries
  • Canonical ScanResult.metadata surfaces dockerfile_path and context_path for build-mode targets and omits them for remote-pull entries — downstream readers don't have to special-case empty strings
  • Extracted the metadata-building logic into a small helper _canonical_container_metadata(result) so the dict shape is unit-testable without spinning up the full engine

2. No audit manifest for container scans

Source scans have always called create_manifest() at start and finalize_manifest() before each exit, writing argus-audit.json alongside argus-results.json. _cmd_container_scan never did. So argus scan container skipped the entire audit-trail layer source scans have.

Fix:

  • Add the same create + finalize bookend in _cmd_container_scan
  • scan_targets lists the Dockerfile path for build-mode entries (or the image ref for remote-pull entries) so the manifest answers "which container produced this run's artifacts?"
  • Unified exit-code computation moved from inline early-returns to a single finalize-and-return at the bottom of the function so every success path goes through the same finalization
  • Engine-error path also finalizes the manifest with EXIT_ERROR before returning

Verification

End-to-end smoke test against the dogfood argus.yml:

argus-results/latest/
├── argus-audit.json    ← NEW (was missing for container scans)
├── argus-results.json
├── argus.log
├── container-scan.md
└── raw/

argus-results.json for a build-mode entry now includes:

{
  "scanner": "container/scanner-bandit",
  "metadata": {
    "image_ref": "scanner-bandit:argus-scan",
    "build_success": true,
    "dockerfile_path": "docker/Dockerfile.bandit",
    "context_path": "."
  }
}

Remote-pull entries omit the dockerfile/context keys (no special-casing needed downstream).

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Tested with different scanner combinations

Test Results

  • 5 new unit tests:
    • TestContainerScanResultDockerfileFields — defaults to empty for remote-pull, populated for build entries
    • TestCanonicalContainerMetadata_canonical_container_metadata(result) omits dockerfile keys for remote-pull, includes them for build, surfaces scanner_errors
  • Full SDK suite: 1585 passing (was 1580 before this PR)
  • argus.audit.test_manifest (existing) covers the manifest-write layer the new _cmd_container_scan consumer plugs into

Security Considerations

  • No security impact
  • Security enhancement
  • Potential security implications (explain below)

Security Details

This is the audit-trail completion that source scans have had since day one. A security reviewer or compliance archive looking at a container scan's artifacts can now trace any finding back to its originating Dockerfile without cross-referencing the workflow definition or shell history. The audit manifest captures the exact targets, config path, exit code, and findings summary at finalize time.

AI Context Updates (.ai/)

  • N/A - No .ai/ updates needed (artifact-shape fix; no architecture or workflow changes)

Checklist

  • Code follows project style guidelines
  • Documentation updated (inline comments + commit message describe the audit-trail symmetry with source scans)
  • Changelog updated (if applicable)
  • All tests pass
  • Reviewed by at least one maintainer
  • Reviewed CONTRIBUTING.md guidelines

For New Scanners/Actions (if applicable)

  • N/A — modifying existing container-scan flow only

…audit.json

Two related gaps in container scan artifacts that block security
review and audit archiving:

1. ContainerScanResult dropped the originating Dockerfile path. The
   target carries it; scan_image() and the engine error paths threw
   it away. So argus-results.json, the per-image markdown, the
   SARIF, and the raw outputs only ever surfaced the auto-derived
   tag like ``scanner-bandit:argus-scan`` — useless to a reviewer
   asking "which Dockerfile produced this finding?".

   Fix: add ``dockerfile`` and ``context`` fields to
   ContainerScanResult and populate them from the target in every
   construction site (scan_image happy path + the three error
   paths in the engine). Empty strings for remote-pull entries.

   The canonical ScanResult metadata in _cmd_container_scan now
   surfaces ``dockerfile_path`` and ``context_path`` for build-mode
   targets and omits them for remote-pull entries (so downstream
   readers don't have to special-case empty strings). Extracted
   the metadata-building logic into a small helper
   ``_canonical_container_metadata(result)`` so the dict shape is
   unit-testable without spinning up the full container engine.

2. Container scans skipped the audit manifest entirely. Source
   scans have always called ``create_manifest()`` at start and
   ``finalize_manifest()`` before exit, writing argus-audit.json
   alongside argus-results.json. _cmd_container_scan never did.

   Fix: add the same create+finalize bookend, with scan_targets
   listing the Dockerfile path for build-mode entries (or the
   image ref for remote-pull entries) so the manifest answers
   "which container produced this run's artifacts?". The unified
   exit-code computation also moved from inline early-returns to a
   single finalize-and-return at the bottom of the function so
   every success path goes through the same finalization.

Tests: 1585 passing (was 1580; +5 new — ContainerScanResult
dockerfile/context defaults, the canonical-metadata helper for
remote-pull, build-mode, and scanner-error cases).

Verified end-to-end: argus scan container now writes both
argus-results.json AND argus-audit.json under the run dir, plus
container-scan.md and the raw/ subdir.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 83.48624% with 18 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
argus/cli.py 35.71% 18 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔒 Argus Container Security Scan

Branch: fix/container-scan-artifacts-dockerfile-and-audit
Commit: 8523ab9

📊 Combined Findings Summary

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low 📦 Total 🔢 Unique
1 22 67 64 154 154

Scanned: 4 containers | Build Failures: 0

📦 Container Breakdown

Container Image 🚨 Crit ⚠️ High 🟡 Med 🔵 Low Total Unique Status
cli ghcr.io/huntridge-labs/argus/cli:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92 1 11 16 1 29 29
scanner-bandit ghcr.io/huntridge-labs/argus/scanner-bandit:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92 0 0 2 0 2 2
scanner-opengrep ghcr.io/huntridge-labs/argus/scanner-opengrep:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92 0 7 44 63 114 114
scanner-supply-chain ghcr.io/huntridge-labs/argus/scanner-supply-chain:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92 0 4 5 0 9 9

🔍 Detailed Findings by Container

🚨 cli - 29 vulnerabilities (23 unique)

Image: ghcr.io/huntridge-labs/argus/cli:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
1 11 16 1 29 23
🔷 Trivy Scanner (29 findings, 23 unique)
CVE Severity Package Version Fixed
CVE-2025-68121 🚨 CRITICAL stdlib v1.24.11 1.24.13, 1.25.7, 1.26.0-rc.3
CVE-2026-32280 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32281 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32283 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-33810 ⚠️ HIGH stdlib v1.26.1 1.26.2
CVE-2025-61726 ⚠️ HIGH stdlib v1.24.11 1.24.12, 1.25.6
CVE-2025-61728 ⚠️ HIGH stdlib v1.24.11 1.24.12, 1.25.6
CVE-2026-25679 ⚠️ HIGH stdlib v1.24.11 1.25.8, 1.26.1
CVE-2026-32280 ⚠️ HIGH stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32281 ⚠️ HIGH stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32283 ⚠️ HIGH stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-34040 ⚠️ HIGH github.com/docker/docker v28.5.2+incompatible 29.3.1
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A
CVE-2026-6357 🟡 MEDIUM pip 26.0.1 26.1
CVE-2026-32282 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32288 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32289 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2025-11579 🟡 MEDIUM github.com/nwaples/rardecode/v2 v2.1.0 2.2.0
CVE-2025-58058 🟡 MEDIUM github.com/ulikunitz/xz v0.5.12 0.5.15
CVE-2025-47914 🟡 MEDIUM golang.org/x/crypto v0.35.0 0.45.0
CVE-2025-58181 🟡 MEDIUM golang.org/x/crypto v0.35.0 0.45.0
CVE-2025-61730 🟡 MEDIUM stdlib v1.24.11 1.24.12, 1.25.6
CVE-2026-27142 🟡 MEDIUM stdlib v1.24.11 1.25.8, 1.26.1
CVE-2026-32282 🟡 MEDIUM stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32288 🟡 MEDIUM stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-32289 🟡 MEDIUM stdlib v1.24.11 1.25.9, 1.26.2
CVE-2026-33997 🟡 MEDIUM github.com/docker/docker v28.5.2+incompatible 29.3.1
CVE-2026-41506 🟡 MEDIUM github.com/go-git/go-git/v5 v5.17.2 5.18.0
CVE-2026-27139 🔵 LOW stdlib v1.24.11 1.25.8, 1.26.1
⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype

🟡 scanner-bandit - 2 vulnerabilities (2 unique)

Image: ghcr.io/huntridge-labs/argus/scanner-bandit:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
0 0 2 0 2 2
🔷 Trivy Scanner (2 findings, 2 unique)
CVE Severity Package Version Fixed
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A
CVE-2026-6357 🟡 MEDIUM pip 26.0.1 26.1
⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype

⚠️ scanner-opengrep - 114 vulnerabilities (50 unique)

Image: ghcr.io/huntridge-labs/argus/scanner-opengrep:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
0 7 44 63 114 50
🔷 Trivy Scanner (114 findings, 49 unique)
CVE Severity Package Version Fixed
CVE-2026-4878 ⚠️ HIGH libcap2 1:2.75-10+b8 N/A
CVE-2025-69720 ⚠️ HIGH libncursesw6 6.5+20250216-2 N/A
CVE-2026-29111 ⚠️ HIGH libsystemd0 257.9-1~deb13u1 N/A
CVE-2025-69720 ⚠️ HIGH libtinfo6 6.5+20250216-2 N/A
CVE-2026-29111 ⚠️ HIGH libudev1 257.9-1~deb13u1 N/A
CVE-2025-69720 ⚠️ HIGH ncurses-base 6.5+20250216-2 N/A
CVE-2025-69720 ⚠️ HIGH ncurses-bin 6.5+20250216-2 N/A
CVE-2026-27456 🟡 MEDIUM bsdutils 1:2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM bsdutils 1:2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM libblkid1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libblkid1 2.41-5 N/A
CVE-2026-4046 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-4437 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-4438 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-5435 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-5450 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-5928 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-6238 🟡 MEDIUM libc-bin 2.41-12+deb13u2 N/A
CVE-2026-4046 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-4437 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-4438 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-5435 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-5450 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-5928 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-6238 🟡 MEDIUM libc6 2.41-12+deb13u2 N/A
CVE-2026-27456 🟡 MEDIUM liblastlog2-2 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM liblastlog2-2 2.41-5 N/A
CVE-2026-34743 🟡 MEDIUM liblzma5 5.8.1-1 N/A
CVE-2026-27456 🟡 MEDIUM libmount1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libmount1 2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM libsmartcols1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libsmartcols1 2.41-5 N/A
CVE-2026-40225 🟡 MEDIUM libsystemd0 257.9-1~deb13u1 N/A
CVE-2026-40226 🟡 MEDIUM libsystemd0 257.9-1~deb13u1 N/A
CVE-2026-4105 🟡 MEDIUM libsystemd0 257.9-1~deb13u1 N/A
CVE-2026-40225 🟡 MEDIUM libudev1 257.9-1~deb13u1 N/A
CVE-2026-40226 🟡 MEDIUM libudev1 257.9-1~deb13u1 N/A
CVE-2026-4105 🟡 MEDIUM libudev1 257.9-1~deb13u1 N/A
CVE-2026-27456 🟡 MEDIUM libuuid1 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM libuuid1 2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM login 1:4.16.0-2+really2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM login 1:4.16.0-2+really2.41-5 N/A
CVE-2026-27456 🟡 MEDIUM mount 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM mount 2.41-5 N/A
CVE-2026-5958 🟡 MEDIUM sed 4.9-2 N/A
CVE-2026-5704 🟡 MEDIUM tar 1.35+dfsg-3.1 N/A
CVE-2026-27456 🟡 MEDIUM util-linux 2.41-5 N/A
CVE-2026-3184 🟡 MEDIUM util-linux 2.41-5 N/A
CVE-2026-27171 🟡 MEDIUM zlib1g 1:1.3.dfsg+really1.3.1-1+b1 N/A
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A

...and 64 more

⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype

⚠️ scanner-supply-chain - 9 vulnerabilities (9 unique)

Image: ghcr.io/huntridge-labs/argus/scanner-supply-chain:8523ab9b90a1bc20901788a0ac1a04e2bd8b6e92

Combined (Deduplicated)

🚨 Critical ⚠️ High 🟡 Medium 🔵 Low Total Unique
0 4 5 0 9 9
🔷 Trivy Scanner (9 findings, 9 unique)
CVE Severity Package Version Fixed
CVE-2026-32280 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32281 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32283 ⚠️ HIGH stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-33810 ⚠️ HIGH stdlib v1.26.1 1.26.2
CVE-2026-3219 🟡 MEDIUM pip 26.0.1 N/A
CVE-2026-6357 🟡 MEDIUM pip 26.0.1 26.1
CVE-2026-32282 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32288 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
CVE-2026-32289 🟡 MEDIUM stdlib v1.26.1 1.25.9, 1.26.2
⚓ Grype Scanner (0 findings, 0 unique)

✅ No vulnerabilities detected by Grype


Generated by Argus

…hreading

Brings codecov/patch above the 80% threshold by exercising the new
dockerfile/context plumbing through every engine path that builds a
ContainerScanResult — build failure, OSError during scan, generic
Exception during scan — plus the happy-path threading from
scan_image. Each test asserts dockerfile and context are populated
from the target (build entries) or empty (remote-pull entries).

Five new tests in TestEngineErrorPathsCarryDockerfile and
TestScanImageThreadsDockerfile.
@eFAILution eFAILution merged commit 18f5d03 into feat/argus-portability May 6, 2026
22 checks passed
@eFAILution eFAILution deleted the fix/container-scan-artifacts-dockerfile-and-audit branch May 6, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant