Warden is an adversarial security review system for any repository. Submit a GitHub or GitLab repo, queue an analysis job, and get back a security report with a verdict, approval conditions, evidence, and repo trust metadata.
- Queues repository analysis jobs from a simple web UI
- Runs a deep security review against a hardened enterprise-focused prompt
- Produces a markdown report plus structured metadata for verdict, risk, trust signals, and approval conditions
- Supports report regeneration with optional steering for follow-up review passes
Warden is designed to be suspicious by default. It explicitly looks for:
- install and postinstall execution
- updater and self-modifying behavior
- remote config and kill switches
- telemetry and hidden exfiltration
- shell execution and command injection paths
- deserialization and template injection
- authorization failures and trust-boundary violations
- secret handling issues
- CI/CD compromise paths
- dependency confusion and supply-chain takeover risk
- attempts inside the repository to manipulate the analyzer itself
Warden is intentionally simple:
server.py: serves the UI and handles submit, queue, report, delete, and regenerate APIsworker/worker.py: clones repos, runs the Claude-based analysis, and writes report artifactssite/: static frontend for submit, queue, reports, and individual report pagessite/data/queue/: queued and in-progress job statesite/data/reports/: generated reports and report index
There is no database. Queue and report state live in JSON files on disk.
- Python 3.11+
uv- Git
- Access to an LLM gateway compatible with the worker
WARDEN_MODEL,OPENAI_COMPATIBLE_ENDPOINT, andNVIDIA_API_KEYexported in your shell
The worker talks to an OpenAI-compatible chat completions API via LangChain. OPENAI_COMPATIBLE_ENDPOINT can point to any service that supports the OpenAI chat completions format, not just one specific vendor.
Example:
export WARDEN_MODEL="your-model-name"
export OPENAI_COMPATIBLE_ENDPOINT="https://your-endpoint.example/v1"
export NVIDIA_API_KEY="your-api-key"Create a .env file and set your runtime values:
WARDEN_MODEL=your-model-name
OPENAI_COMPATIBLE_ENDPOINT=https://your-endpoint.example/v1
NVIDIA_API_KEY=your-api-keyOptional hardening knobs:
# Require Authorization: Bearer <token>, X-Warden-Token, or Basic auth for API writes/reads.
WARDEN_API_TOKEN=choose-a-long-random-token
# Leave unset for same-origin browser use. Set only when a trusted cross-origin UI is required.
WARDEN_CORS_ORIGIN=https://warden.example.com
# Maximum regeneration steering size in bytes.
MAX_STEERING_BYTES=2000uv run server.pyIn a second terminal:
uv run worker/worker.py --watchThen open:
http://localhost:12000
Drain all pending work:
uv run worker/worker.pyProcess a single job and then continue draining backlog:
uv run worker/worker.py --job <job-id>Queue the current GitHub Trending repositories:
uv run github_trending.pyRun it as a lightweight daily scheduler:
uv run github_trending.py --watch --interval-hours 24Useful options:
uv run github_trending.py --max-repos 10 --dedupe-days 30
uv run github_trending.py --no-trigger-workerThe Docker deployment includes a trending service that runs this intake loop every 24 hours and writes to the same queue volume as the worker service. The importer fetches the GitHub Trending HTML page once per run with browser-like headers instead of calling the GitHub API repeatedly. It skips repositories that are already active in the queue and repositories with a completed report inside the dedupe window, which defaults to 30 days. If GitHub rate-limits or rejects the fetch, the run exits cleanly without mutating the queue.
Create a .env file with:
WARDEN_MODEL=your-model-name
OPENAI_COMPATIBLE_ENDPOINT=https://your-endpoint.example/v1
NVIDIA_API_KEY=your-api-keyOPENAI_COMPATIBLE_ENDPOINT can be any endpoint that supports the OpenAI chat completions format.
Start the app:
docker compose up --build -dThis starts the web server, the queue-draining worker, and the daily GitHub Trending intake service.
Open:
http://localhost:12000
Stop it:
docker compose down- Submit a repository URL from the home page
- Warden adds the repo to the queue and triggers the worker when capacity is available
- The worker clones the repo into a temporary directory and runs the security analysis
- Warden writes:
- a markdown report
- structured sidebar metadata
- an index entry for the reports table
- The report page renders the markdown report with verdict, risk, trust signals, and approval conditions
The web UI uses the same runtime state exposed by the API. Agent callers only need one stable ID: the jobId returned by submit. That ID is also the completed report ID.
Submit a repository:
curl -s http://localhost:12000/api/submit \
-H 'Content-Type: application/json' \
-d '{
"url": "https://github.com/openai/openai-python",
"ecosystem": "auto",
"severity": "low",
"depth": "shallow"
}'The response includes jobId, statusUrl, reportUrl, and links.
Poll job status:
curl -s http://localhost:12000/api/jobs/<job-id>Status is pending, processing, failed, or succeeded. When a worker completes a job, Warden removes it from the queue and /api/jobs/<job-id> returns succeeded by resolving the completed report.
Get a completed report:
curl -s http://localhost:12000/api/reports/<report-id> -o warden-report.jsonReports include full markdown content and can be long. Write them to a file first, then inspect with jq, an editor, or a pager.
Search reports for a repository:
curl -s 'http://localhost:12000/api/reports?provider=github&owner=openai&repo=openai-python' -o warden-report-search.json
curl -s 'http://localhost:12000/api/reports?repository=openai/openai-python' -o warden-report-search.jsonSearch responses are smaller than full reports, but writing them to a file keeps terminal output predictable.
Each analysis produces:
- an overall verdict:
approve,conditional, orreject - an overall risk level
- approval conditions near the top of the report
- a detailed markdown narrative with findings and evidence
- deterministic repository metadata such as stars, forks, contributors, open issues, creation date, license, and
SECURITY.mdpresence
Existing reports can be regenerated from the UI.
- Regeneration reuses the same report ID
- The completed run overwrites the previous report entry
- Optional steering can be supplied for follow-up analysis
- Steering is appended only for regeneration jobs and does not replace the core adversarial prompt
- Restart the server after changing
server.py - Worker changes apply on the next worker spawn
- Static asset changes usually only require a hard refresh
- Queue and report artifacts are local runtime data, not durable storage
Warden is built for repository review, not runtime sandboxing or malware detonation. It is strongest as a review gate for repo intake, internal security triage, and follow-up analysis on suspicious repos.


