GitHub Safety Scanner is a self-hosted FastAPI web app for reviewing public GitHub repositories with a fixed battery of static, dependency, vulnerability, SBOM, and secret scanners.
It accepts a public GitHub HTTPS repository URL, shallow-clones it into an isolated temporary workspace, runs scanners without executing repository code, and renders deterministic HTML, Markdown, and raw JSON artifacts.
- Accepts only public
https://github.com/{owner}/{repo}or.gitURLs. - Rejects credentials, query strings, fragments, ports, encoded slashes, extra paths, non-HTTPS URLs, and non-GitHub hosts.
- Clones with
git -c core.symlinks=false clone --depth=1 --single-branch --no-tags --no-recurse-submodules. - Never executes repository code, hooks, package managers, installs, builds, or tests.
- Uses subprocess argument lists only (
shell=False). - Cleans temporary clone workspaces after success, failure, or timeout.
- Docker Compose binds only to
127.0.0.1:8080, uses a named data volume, does not mount the Docker socket or host home directory, enablesno-new-privileges, and drops Linux capabilities. - Intended for repositories you own, maintain, or have permission to assess. Scanner output can include file paths and snippets from the scanned repository.
The intended scanner battery is:
- Trivy: vulnerability, secret, and misconfiguration findings.
- Gitleaks: secret detection.
- Semgrep: static analysis with bundled rules.
- OSV-Scanner: dependency vulnerability checks.
- Syft: SBOM generation.
- Grype: SBOM/package vulnerability checks.
If one scanner is missing or fails, the worker records that scanner as failed in scanner_runs and still produces a report when possible. Clone failure fails the scan.
Build and run locally with Docker Compose:
git clone https://github.com/santastabber/github-safety-scanner.git
cd github-safety-scanner
docker compose up --buildOpen the app at:
http://127.0.0.1:8080
Validate the Compose file without starting the app:
docker compose configStop and remove the container while preserving the named data volume:
docker compose downThese commands prepare a Docker Hub image locally without logging in or pushing.
Replace your-dockerhub-user with the approved Docker Hub namespace before any
real publication.
Build the local image:
docker build -t repo-safety-scanner:local .Tag it for Docker Hub:
docker tag repo-safety-scanner:local your-dockerhub-user/repo-safety-scanner:latestRun the local image:
docker run --rm \
-p 127.0.0.1:8080:8080 \
-v repo_safety_scanner_data:/app/data \
repo-safety-scanner:localSmoke test the running scanner service:
curl -fsS http://127.0.0.1:8080/Use the helper script to run tests, validate Compose, build the local image, and
apply the Docker Hub tag. It does not run docker login or docker push.
./scripts/prepare_dockerhub.sh
DOCKERHUB_IMAGE=your-dockerhub-user/repo-safety-scanner:latest ./scripts/prepare_dockerhub.shPublishing still requires explicit approval, a real Docker Hub namespace, and a logged-in Docker client. After approval only, use:
docker login
docker push your-dockerhub-user/repo-safety-scanner:latestUse uv so dependencies are installed into the project virtual environment, not globally:
git clone https://github.com/santastabber/github-safety-scanner.git
cd github-safety-scanner
uv venv --python 3.12 || uv venv
uv pip install -e '.[test]'
uv run python -m pytest -vRun linting when Ruff is installed:
uv run ruff check .Run the app without Docker:
uv run uvicorn repo_safety_scanner.app:get_app --factory --host 127.0.0.1 --port 8080src/repo_safety_scanner/app.py: FastAPI app factory and routes.src/repo_safety_scanner/worker.py: scan queue worker orchestration.src/repo_safety_scanner/scanner.py: fixed scanner command construction and subprocess execution.src/repo_safety_scanner/reports.py: report parsing and rendering helpers.tests/: pytest coverage for validation, scanner command safety, reports, Dockerfile, and Compose hardening.
This repository is prepared for publication at:
https://github.com/santastabber/github-safety-scanner