TagTrawler scans Docker images for potential secrets by inspecting:
- Environment variables (verbatim)
- Filesystem “interesting filenames” (e.g.,
.env, key material, backups, disk images) - File content regex hits (with line number and matching line text)
TagTrawler is intended solely for security auditing in authorized environments (e.g., your own systems, or systems you have explicit permission to assess). Do not use this tool to access, scan, or collect data from images, registries, or infrastructure without written authorization and a clear scope of work.
Disclaimer: This project is provided “AS IS”, without warranty of any kind. The author(s) and contributors assume no responsibility or liability for misuse, unlawful use, damages, or compliance failures arising from use of this tool. You are solely responsible for ensuring your use complies with applicable laws, policies, contracts, and ethical guidelines.
pip install -r requirements.txtpython3 TagTrawler.py -r <USERNAME>/<REPO> --all-tags --verbosepython3 TagTrawler.py -r <USERNAME>/<REPO> --specific-tag prod --verboseTagTrawler relies on your existing local Docker authentication wherever possible:
-
Pulling images uses your Docker daemon via the Docker SDK, so it uses whatever is already configured by:
docker login ...- credential helpers (e.g.,
docker-credential-*) - cloud CLIs that configure Docker (e.g.,
az acr login,gcloud auth configure-docker)
-
Tag enumeration
- Docker Hub: uses the registry token flow (auth.docker.io + registry-1.docker.io). If the repo is private, it will attempt to use your Docker Hub credentials from
~/.docker/config.json/ credential helpers. - AWS ECR: uses AWS APIs via
boto3(needs AWS credentials/region). - GCR/Artifact Registry: uses registry tag listing; typically works when your Docker credential helper is configured.
- Azure ACR: uses ACR’s HTTP API (
/acr/v1/.../_tags) and obtains a bearer token using your existing Docker login / credential helper.
- Docker Hub: uses the registry token flow (auth.docker.io + registry-1.docker.io). If the repo is private, it will attempt to use your Docker Hub credentials from
If docker pull <image:tag> works in your environment, TagTrawler can generally scan that tag. Please note that at this time, only docker hub authentication has been tested.
- Public images: no auth required for scanning.
- Private images / tag enumeration: authenticate with Docker first.
docker loginTagTrawler needs AWS credentials for tag enumeration.
Typical login flow:
aws sts get-caller-identity
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <acct>.dkr.ecr.<region>.amazonaws.comThen scan:
python3 TagTrawler.py -r <acct>.dkr.ecr.<region>.amazonaws.com/<repo> --all-tags --verboseConfigure Docker auth via gcloud:
gcloud auth login
gcloud auth configure-dockerThen scan:
python3 TagTrawler.py -r gcr.io/<project>/<image> --all-tags --verbose
# or Artifact Registry
python3 TagTrawler.py -r <region>-docker.pkg.dev/<project>/<repo>/<image> --all-tags --verboseAuthenticate with Azure and configure Docker:
az login
az acr login -n <registryName>Then scan:
python3 TagTrawler.py -r <registryName>.azurecr.io/<repo>/<image> --all-tags --verboseBy default, TagTrawler uses --mode linux-container, optimized for typical Linux-based container images:
- Avoids common base-image noise (docs/manpages/package caches)
- Avoids scanning binary blobs as text (printable “textiness” check)
- Prioritizes common application roots (
/app,/opt,/srv,/workspace,/var/www,/home,/root,/usr/local) - Still flags risky artifacts (e.g.,
.vhd/.vhdx/.iso/.ova/.ovf) as filename hits
You can switch to minimal filtering:
python3 TagTrawler.py -r <image> --mode default --verboseAdd additional excludes:
python3 TagTrawler.py -r <image> --all-tags --exclude-path-regex '^/usr/share/zoneinfo(/|$)' --verboseControl content scanning:
python3 TagTrawler.py -r <image> --all-tags --max-content-file-bytes 262144 --verbose
python3 TagTrawler.py -r <image> --all-tags --content-ext .pem --content-ext .conf --verbose-r / --remote <image-or-repo>: image referencenamespace/repo:tag(Docker Hub)registry/repo:tag(ECR/GCR/ACR/etc.)
--all-tags: enumerate and scan all tags for each-rreference--specific-tag <tag>: scan only one tag (overrides any tag in-rand skips enumeration)
--threads <n>: parallel tag scanning (default: modest value)--max-bytes <n>: maximum bytes read per file (content inspection)--max-content-file-bytes <n>: skip content scanning for files larger than this (default 512KB)--scan-path /path: restrict extraction scan to one or more absolute paths (repeatable)
--registry dockerhub|ecr|gcr|acr|other: override auto-detection
-o / --output <file.json>: output JSON path
Each scanned image:tag produces one row containing:
image: fully qualified image:tagenvironment_variables: rawKEY=valuelist from the image configinteresting_environment_variables: subset filtered by key-name heuristics (KEY/TOKEN/SECRET/URL/etc.)filename_hits: absolute paths of files whose names match filename patternscontent_hits: list of:file: absolute pathmatched_patterns: unique regex patterns matchedmatches: list of{pattern, line_number, line}
TagTrawler writes output even if you interrupt with Ctrl+C (partial results are preserved).
python3 TagTrawler.py -r <repo> --all-tags --verbose
jq -r '.rows[] | {image, interesting_environment_variables, filename_hits, content_hits_count:(.content_hits|length)}' < report.jsonpython3 TagTrawler.py -r <repo> --all-tags --scan-path /app --scan-path /opt --verboseUse a regex config file to customize patterns (optional):
python3 TagTrawler.py -r <repo> --all-tags --regex-config my_regexes.json --verbose- Content scanning is best-effort and intentionally constrained to limit noise and runtime.
- Images are pulled locally; ensure you have sufficient disk space.
- For very large number of images/tags, increase
--threadscautiously to avoid saturating registry limits.
TagTrawler may surface sensitive information. Treat reports as sensitive artifacts:
- Store them securely
- Avoid uploading them to shared systems without access controls
- Consider encrypting reports at rest if they contain real secrets