Your guide to the scanner and command line.
This site mirrors the current repository layout, additionally including an in-browser demo.
This site mirrors the current repository layout, additionally including an in-browser demo.
layerleak currently targets Go 1.24+ and builds directly from source.
git clone https://github.com/brumbelow/layerleak.git
cd layerleak
go build -o layerleak .
Optional local configuration still uses a plain environment file:
cp .env.example .env
The scanner keeps its runtime surface small: registry endpoints, output location, HTTP timeout, operational guardrails, and optional Postgres persistence.
export LAYERLEAK_FINDINGS_DIR=findings
export LAYERLEAK_API_ADDR=127.0.0.1:8080
export LAYERLEAK_TAG_PAGE_SIZE=100
export LAYERLEAK_MAX_MANIFEST_BYTES=0
export LAYERLEAK_MAX_CONFIG_BYTES=0
export LAYERLEAK_MAX_REPOSITORY_TAGS=0
export LAYERLEAK_MAX_REPOSITORY_TARGETS=0
export LAYERLEAK_REGISTRY_REQUEST_ATTEMPTS=2
export LAYERLEAK_DATABASE_URL=postgres://postgres:postgres@localhost:5432/layerleak?sslmode=disable
The four size and repository caps are disabled when set to 0.
If enabled and exceeded, the scan fails closed but still preserves partial results.
Actionable findings drive the CLI exit code and stay visible in findings.
Example or tutorial-like material is retained as suppressed findings with
disposition metadata for review.
Saved findings files and local Postgres storage both keep raw finding material on purpose. CLI and API output stay redacted.
Use a dedicated local database or schema for layerleak. Persistence stores raw values and raw snippets, not just redacted previews.
Migrations are manual by design. The scanner does not auto-create or auto-upgrade the schema.
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0001_initial.up.sql
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0002_finding_occurrence_metadata.up.sql
The current schema keeps live deduplicated state by repository, tag, manifest,
fingerprint, and occurrence metadata. It does not keep a separate scan_runs
history table yet.
The primary command surface is still the scanner CLI.
./layerleak --help
./layerleak scan --help
./layerleak scan ubuntu
./layerleak scan library/nginx:latest --format json
./layerleak scan alpine:latest --platform linux/amd64
./layerleak scan mongo
Bare repository names enumerate public tags. If you only want a single image, use an explicit tag or digest.
The API is a separate Go binary under cmd/api. It requires
LAYERLEAK_DATABASE_URL and serves JSON only.
go run ./cmd/api
Current endpoints:
POST /api/v1/scans
GET /api/v1/repositories
GET /api/v1/repositories/{repository}/findings
GET /api/v1/findings/{id}
API responses mirror the redacted CLI/API view. They never expose raw secret values or raw snippets from local storage.
The GitHub Pages demo is intentionally simulated. It replays a fixed scan command and then shows a fake local Postgres snapshot that matches the storage model conceptually.
layerleak scan vulnerableHost:latest --platform linux/amd64
The transcript, findings file path, and database rows are all synthetic and versioned in-repo as static fixture data.