This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Dockle is OSS for a worldwide audience. Everything that ends up in Git history — commit messages, code comments, documentation, test fixtures, PR titles and descriptions — must be written in English.
Dockle is a container image linter for security, written in Go. It scans built Docker images (not Dockerfiles) against CIS Benchmark checkpoints (CIS-DI-*) and Dockle original checkpoints (DKL-DI-* for Docker best practices, DKL-LI-* for Linux best practices). All checkpoints are documented in CHECKPOINT.md.
# Build
go build -o dockle cmd/dockle/main.go
# Run all tests (CI runs with CGO_ENABLED=0)
go test ./...
# Run tests for a single package
go test ./pkg/assessor/manifest/
# Run a single test
go test ./pkg/assessor/manifest/ -run TestAssess
# Run locally against an image
./dockle [IMAGE_NAME]
./dockle --input image.tar # scan a saved image fileReleases are built by GoReleaser (goreleaser.yaml) via GitHub Actions when a v* tag is pushed (.github/workflows/releasebuild.yml).
The scan pipeline flows: CLI → scanner → extractor (pkg/deckoder) → assessors → assessment map → report writer.
-
Entry point:
cmd/dockle/main.gocallspkg.NewApp()(pkg/app.go), which defines all CLI flags usingurfave/cliv3. The action ispkg.Run(pkg/run.go), which wires everything together.config.CreateFromCli(config/config.go) populates the globalconfig.Conf(ignore rules from flags/DOCKLE_IGNORES/.dockleignore, exit code, etc.). -
Image extraction:
pkg/scanner/scan.gousespkg/deckoder(formerly the separategithub.com/goodwithtech/deckoderlibrary, now integrated into this repository — seepkg/deckoder/README.md) to fetch the image from a Docker daemon, remote registry, or tar archive. Only files that assessors declare they need — viaRequiredFiles()/RequiredExtensions()/RequiredPermissions()— are extracted, using a tar filter function. Acceptance flags (--accept-file,--accept-file-extension) remove files from that filter. -
Assessors (
pkg/assessor/): each subpackage implements theAssessorinterface (assessor.go) and is registered in itsinit()-style list inpkg/assessor/assessor.go. Each assessor inspects the extractedFileMapand returns[]*types.Assessmenttagged with a checkpoint code. Themanifestassessor is the largest — it parses image config/history to lint Dockerfile-derived instructions. Assessor-level allow/deny lists (sensitive words, credential file names) are injected from CLI flags inpkg/run.go. -
Checkpoint definitions:
pkg/types/checkpoint.goholds the code constants,DefaultLevelMap(FATAL/WARN/INFO/SKIP/PASS levels), andTitleMap.types.CreateAssessmentMap(pkg/types/assessment.go) groups assessments and applies ignores/levels. -
Output:
pkg/report/has threeWriterimplementations — list (default, colored), JSON, SARIF — selected by--format. The writer returnsabend, which combined with--exit-code/--exit-leveldetermines the process exit status.
Touch all of these: code constant + level + title in pkg/types/checkpoint.go, detection logic in the relevant assessor under pkg/assessor/ (or a new assessor registered in pkg/assessor/assessor.go), documentation in CHECKPOINT.md, and the summary table in README.md.
Tests are table-driven and live next to the code. The manifest assessor tests use JSON image-config fixtures in pkg/assessor/manifest/testdata/; SARIF writer tests compare against golden files in pkg/report/testdata/.