Optimized Docker container for forensic credential extraction with enhanced security and minimal footprint.
- Minimal Size: <50MB final image using multi-stage Alpine build
- Security Hardened: Non-root execution, read-only rootfs, no capabilities
- Forensic Integrity: Read-only data mounts, pre-execution safety checks
- Network Isolated: No network access by default (network_mode: none)
- Resource Limited: CPU and memory constraints for controlled environments
cd docker/
docker-compose build-
Place Jenkins files in
jenkins_files/directory:mkdir -p jenkins_files output # Copy your Jenkins files: # - master.key # - hudson.util.Secret # - credentials.xml (optional)
-
Run the decryptor:
# View help docker-compose run --rm jenkins-decrypt --help # Decrypt and display (sanitized by default) docker-compose run --rm jenkins-decrypt --path /data # Decrypt and export to JSON docker-compose run --rm jenkins-decrypt --path /data --export-json /output/loot.json # Decrypt with revealed secrets docker-compose run --rm jenkins-decrypt --path /data --export-json /output/loot.json --reveal-secrets # Export to CSV docker-compose run --rm jenkins-decrypt --path /data --export-csv /output/loot.csv --reveal-secrets
Container runs as user forensic:forensic (UID:GID 1000:1000), not root.
read_only: truePrevents any modifications to container filesystem, ensuring forensic integrity.
cap_drop:
- ALLRemoves all Linux capabilities, minimizing attack surface.
network_mode: noneNo network access required or allowed. Pure local file processing.
limits:
cpus: '0.5'
memory: 128MControlled resource usage for restricted environments.
Mount your Jenkins files here:
volumes:
- ./jenkins_files:/data:roThe :ro flag ensures forensic integrity - no modifications possible.
Export decrypted credentials here:
volumes:
- ./output:/outputTemporary filesystem for Python bytecode when using read-only rootfs:
- type: tmpfs
target: /tmp
tmpfs:
size: 10MThe entrypoint script performs pre-execution validation:
- User Check: Warns if running as root
- /data Existence: Verifies mount point exists
- /data Write Status: Warns if not read-only
- File Discovery: Checks for master.key, hudson.util.Secret, credentials.xml
- Export Path: Validates export directory is writable
Start a Jenkins lab environment for testing:
# Start Jenkins lab
docker-compose --profile lab up -d jenkins-lab
# Wait for startup (2-3 minutes)
docker-compose logs -f jenkins-lab
# Access at http://localhost:8080
# Extract credentials from running Jenkins
docker exec jenkins-lab-target cat /var/jenkins_home/secrets/master.key > jenkins_files/master.key
docker exec jenkins-lab-target cat /var/jenkins_home/secrets/hudson.util.Secret > jenkins_files/hudson.util.Secret
docker exec jenkins-lab-target cat /var/jenkins_home/credentials.xml > jenkins_files/credentials.xml 2>/dev/null
# Run decryptor against extracted files
docker-compose run --rm jenkins-decrypt --path /data --export-json /output/loot.json --reveal-secretsdocker build -f docker/Dockerfile -t jenkins-decrypt:custom ..docker-compose run --rm --entrypoint jenkins-decrypt jenkins-decrypt --helpdocker-compose run --rm --entrypoint /bin/sh jenkins-decryptdocker buildx build --platform linux/amd64,linux/arm64 -t jenkins-decrypt:multi -f docker/Dockerfile ..The multi-stage build achieves minimal size through:
- Builder Stage: Uses Alpine with build dependencies (gcc, musl-dev)
- Final Stage: Copies only virtual environment, no build tools
- Python Alpine: Base image ~45MB vs ~120MB for python:slim
- No Cache:
pip install --no-cache-dirremoves package caches - Minimal Dependencies: Only pycryptodome required (pure crypto, no web frameworks)
Expected final size: ~40-48MB
Scan the image for vulnerabilities:
# Using Trivy
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image jenkins-credential-decryptor:2.0.0
# Using Grype
grype jenkins-credential-decryptor:2.0.0Ensure files are mounted correctly:
ls -la jenkins_files/
# Should show: master.key, hudson.util.Secret, credentials.xmlCheck output directory permissions:
chmod 755 output/
chown 1000:1000 output/ # Match container userThis is expected and secure. Ensure you're mounting /output for exports:
volumes:
- ./output:/outputFor production forensic operations:
- Use read-only data mounts (
:roflag) - Enable logging to capture all operations
- Set resource limits appropriate to environment
- Disable network (default configuration)
- Scan image before deployment
- Use specific version tags, not
latest
Example:
docker run --rm \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges:true \
--network=none \
-v ./jenkins_files:/data:ro \
-v ./output:/output \
-v /tmp \
jenkins-credential-decryptor:2.0.0 \
--path /data --export-json /output/loot.jsonMIT License - See LICENSE file