feat(providers): add Dockerfile/Containerfile provider for image analysis - #542
Conversation
…ysis Add DockerfileProvider that parses FROM instructions to extract base image references and generates CycloneDX SBOMs via syft. Supports multi-stage builds (uses final FROM), suffixed filenames (Dockerfile.dev), multiple --flag tokens, and rejects ARG substitution and FROM scratch. Also normalize Docker Hub image references in ImageRef.getPackageURL() so bare names (node) and library-prefixed names (docker.io/library/node) produce the same PURL (docker.io/node), aligning with the JS client. Implements: TC-4938 Assisted-by: Claude Code Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reviewer's GuideAdds a Dockerfile/Containerfile provider that parses FROM instructions to derive a base image, generates a CycloneDX SBOM via syft, and normalizes Docker Hub image references in ImageRef PURLs, with tests covering multi-stage Dockerfiles, flags, ARG substitution, scratch images, filename resolution, and Docker Hub normalization behavior. Sequence diagram for DockerfileProvider SBOM generation from DockerfilesequenceDiagram
participant Ecosystem
participant DockerfileProvider
participant ImageUtils
participant ImageRef
Ecosystem->>Ecosystem: getProvider(manifestPath)
Ecosystem->>Ecosystem: isDockerfile(filename)
Ecosystem-->>DockerfileProvider: new DockerfileProvider(manifestPath)
DockerfileProvider->>DockerfileProvider: provideComponent()
DockerfileProvider->>DockerfileProvider: generateSbomContent()
DockerfileProvider->>DockerfileProvider: parseLastFromImage(manifestPath)
DockerfileProvider-->>ImageUtils: parseImageRef(imageReference)
ImageUtils-->>DockerfileProvider: ImageRef
DockerfileProvider->>ImageUtils: generateImageSBOM(imageRef)
ImageUtils-->>DockerfileProvider: sbomNode
DockerfileProvider->>DockerfileProvider: objectMapper.writeValueAsBytes(sbomNode)
DockerfileProvider-->>Ecosystem: Content(CYCLONEDX_MEDIA_TYPE)
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The Dockerfile provider’s FROM parsing currently only checks for
${to detect ARG substitution; consider using a more robust pattern (e.g. matching${...}tokens in the image segment) to avoid false positives/negatives if${appears in other contexts on the line. - In
ImageRef.getPackageURL, Docker Hublibrary/normalization lowercases the entire repository string, which may unintentionally lose case information for user-controlled segments; consider normalizing only thelibrary/prefix while preserving the original case of the image name.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The Dockerfile provider’s FROM parsing currently only checks for `${` to detect ARG substitution; consider using a more robust pattern (e.g. matching `${...}` tokens in the image segment) to avoid false positives/negatives if `${` appears in other contexts on the line.
- In `ImageRef.getPackageURL`, Docker Hub `library/` normalization lowercases the entire repository string, which may unintentionally lose case information for user-controlled segments; consider normalizing only the `library/` prefix while preserving the original case of the image name.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #542 +/- ##
=======================================
Coverage ? 69.34%
Complexity ? 1040
=======================================
Files ? 66
Lines ? 4371
Branches ? 774
=======================================
Hits ? 3031
Misses ? 993
Partials ? 347
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
[sdlc-workflow/verify-pr] Re: @sourcery-ai[bot] review —
|
Verification Report for TC-4938 (commit bf0257f)
Overall: PASSAll acceptance criteria are satisfied. CI passes across all platforms. The two WARN items are informational:
This comment was AI-generated by sdlc-workflow/verify-pr v0.11.0. |
Aligns with the JavaScript client by allowing users to set TRUSTIFY_DA_RECOMMEND=false to append ?recommend=false to analysis URLs, disabling Trusted Content recommendations in responses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Adva Oren <aoren@redhat.com>
Merge artifact caused duplicate class declaration and missing braces. Restored correct version from PR guacsec#546 which tests new parseAllFromImages batch behavior. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Merge conflict caused duplicate uri declarations in three methods. Removed first buildAnalysisUri calls - resolveAnalysisUri already chooses correct endpoint based on batch flag. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Summary
DockerfileProviderthat parsesFROMinstructions to extract the base image reference and generates a CycloneDX SBOM via syft for component and stack analysisFROM), suffixed filenames (Dockerfile.dev,Containerfile.prod), multiple--flagtokens, and rejectARGsubstitution andFROM scratchImageRef.getPackageURL()so bare names (node) and library-prefixed names (docker.io/library/node) produce the same PURL (docker.io/node)Implements TC-4938
Test plan
Ecosystem.resolveProviderreturnsDockerfileProviderforDockerfile,Containerfile, and suffixed variants--flagtokenshttpd@sha256:...)FROM scratchreadLicenseFromManifestreturns nullvalidateLockFiledoes not throwDockerfilesomething) is rejecteddocker.io/nodein PURLlibrary/prefix stripped in PURLdocker.io/myuser/myimage) unchanged in PURL🤖 Generated with Claude Code
Summary by Sourcery
Enhancements: