GitHub - jdubansky/codeWOPR: Scan bad code using openAI

4 min read Original article ↗

codeWOPR

codeWOPR screenshot 1 codeWOPR screenshot 2
codeWOPR screenshot 3 codeWOPR screenshot 4
Overview, scan triggering, findings, and details



Two-part Python project:

  • Scanner CLI: runs standalone SAST scans on a folder and prints JSON findings
  • Management server: launches scans, ingests results into SQLite, and provides a minimal web UI

Quickstart

  1. Create venv and install
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
  1. Configure environment
cp env.example .env
export $(grep -v '^#' .env | xargs)  # or use a shell that auto-loads .env
  1. Run scanner (standalone)
codewopr-scanner scan --path /path/to/repo --model gpt-4o-mini

CI/CD ingestion to management console

Post scan results to the running console (auto-creates/updates the Project):

# The CLI still prints JSON to stdout; posting is optional.
codewopr-scanner scan \
  --path /path/to/repo \
  --model gpt-4o-mini \
  --concurrency 8 \
  --include-related \
  --post-to http://localhost:3000 \
  --project-name my-repo

Branch / PR-only scans

Scan only the files changed on a branch (diff vs merge-base with HEAD):

codewopr-scanner scan \
  --path /path/to/repo \
  --model gpt-4o-mini \
  --branch Feature7 \
  --concurrency 8 \
  --post-to http://localhost:3000 \
  --project-name my-repo

Scan only the files changed between two refs (explicit base/head):

codewopr-scanner scan \
  --path /path/to/repo \
  --model gpt-4o-mini \
  --git-base origin/main --git-head Feature7 \
  --post-to http://localhost:3000 \
  --project-name my-repo

Scan only the files in a GitHub PR (uses GitHub API; set GITHUB_TOKEN or GH_TOKEN if needed):

codewopr-scanner scan \
  --path /path/to/repo \
  --model gpt-4o-mini \
  --github-pr juice-shop/juice-shop#2783 \
  --post-to http://localhost:3000 \
  --project-name juice-shop

Scan only your working tree changes vs HEAD:

codewopr-scanner scan --path /path/to/repo --model gpt-4o-mini --only-changed

Run the CLI without activating the venv

You can invoke the CLI directly using the venv binaries or by adjusting PATH:

# 1) Direct console script
~/codeWOPR/.venv/bin/codewopr-scanner scan --path /path --model gpt-4o-mini

# 2) Module invocation with the venv's Python
~/codeWOPR/.venv/bin/python -m scanner.cli scan --path /path --model gpt-4o-mini

# 3) Temporary PATH prepend
PATH=~/codeWOPR/.venv/bin:$PATH \
codewopr-scanner scan --path /path --model gpt-4o-mini

# 4) Inline env vars (e.g., OpenAI key) with direct binary
OPENAI_API_KEY=YOUR_KEY \
~/codeWOPR/.venv/bin/codewopr-scanner scan --path /path --model gpt-4o-mini

Alternate ways to run the scanner (equivalent):

# 1) Console script (shown above)
codewopr-scanner scan --path "~/WebGoat" --model gpt-4o-mini --verbose

# 2) Module invocation (no entrypoint needed)
python -m scanner.cli scan --path "~/WebGoat" --model gpt-4o-mini --verbose

# 3) Direct file execution (ensure PYTHONPATH points to repo root)
PYTHONPATH=~/codeWOPR \
python ~/codeWOPR/scanner/cli.py scan --path "~/WebGoat" --model gpt-4o-mini --verbose
  1. Run management server
codewopr-manager --reload

Open http://localhost:3000 to use the UI (default port can be overridden with --port or PORT).

Docker

Build the container image (includes both the management server and scanner CLI):

docker build -t codewopr:latest .

Run it locally (mount a host directory to persist the SQLite database):

mkdir -p ./data
docker run --rm -p 3000:3000 \
  -e OPENAI_API_KEY=sk-... \
  -e DATABASE_URL=sqlite:////data/codewopr.db \
  -v "$(pwd)/data":/data \
  --name codewopr \
  codewopr:latest

The container defaults to HOST=0.0.0.0 and listens on PORT=3000. You can still run the scanner CLI inside the image if needed:

docker run --rm -it \
  -e OPENAI_API_KEY=sk-... \
  -v /path/to/project:/scan \
  codewopr:latest \
  codewopr-scanner scan --path /scan --model gpt-4o-mini

Kubernetes

  1. Build and push the image to a registry your cluster can access:
docker build -t ghcr.io/your-org/codewopr:latest .
docker push ghcr.io/your-org/codewopr:latest
  1. Create a secret that holds the OpenAI API key:
kubectl create secret generic openai-api \
  --from-literal=api-key=sk-your-key
  1. Apply the sample manifests (PVC + Deployment + Service):
kubectl apply -f deploy/k8s/deployment.yaml

The deployment:

  • Mounts a persistent volume at /data and points DATABASE_URL to sqlite:////data/codewopr.db.
  • Exposes the web UI on port 80 via a ClusterIP service (change to LoadBalancer/Ingress as needed).
  • Pulls its OpenAI API key from the openai-api secret.

Customize the image name, resource requests, and replicas for your environment. For production, consider using an external database (e.g., Postgres) by setting DATABASE_URL and removing the volume mount.

Notes

  • Requires Python 3.11+
  • Uses SQLite by default; see DATABASE_URL in .env
  • OpenAI key required: set OPENAI_API_KEY
  • Some models (e.g., gpt-5) enforce a fixed temperature. The scanner automatically omits the temperature param for these to avoid errors.