The Problem
Security researchers and developers need a controlled way to have AI agents find vulnerabilities in code without the noise and unreliability of dumping entire repositories into a single model prompt. open·kritt addresses this by breaking research into focused, well-defined tasks that AI agents can run in parallel, then combining output into de-duplicated, ranked findings with configurable validation.
What This Does
open·kritt is a self-hosted platform comprising five semi-independent projects. The frontend (119 files, 105 code files in frontend/) provides the UI for workflow building and scan management, built with React and accessible at http://localhost:5173. The backend (73 files, 66 code files in backend/) handles API, scan orchestration, and database operations via Express and Prisma ORM, with entry points at backend/src/app.js and backend/src/server.js. The engine (50 files, 44 code files in engine/) contains the core orchestration logic in engine/open_kritt_engine/, including the worker module that has 22 outgoing import edges and instability of 0.96. The database layer (38 files, 35 code files in database/) uses Prisma schema, and executor-view (3 files, 2 code files) provides a separate execution interface. The system enables building reusable security research playbooks, running scans against remote or local repositories, verifying findings via post-scripts, and exporting results with proofs of concept in a share-safe ZIP archive.
How It Is Wired
Control flows through distinct entry points depending on the mode. The web UI starts at frontend/index.html which routes to frontend/src/pages/CreateScan, a hub module with 23 importers and instability 0.9. The backend entry backend/src/app.js is the primary API server, which depends on backend/src/db (18 importers, no outgoing imports, instability 0). Scans are orchestrated through engine/open_kritt_engine/__main__.py, which connects to the worker at engine/open_kritt_engine/worker – the most connected module in the graph with 22 import edges. The worker spawns agent execution, and findings flow through backend/src/lib/validation.js and backend/src/lib/serialize.js, which have high branching density (62 branch points over 185 lines). The router at frontend/src/router has 19 outgoing edges and instability 0.95, indicating frequent reconfiguration. Database operations go through Prisma in backend/prisma/, and outbound API calls to model providers originate from backend/src/lib/modelProviders.js and backend/src/lib/modelSelection.js. The frontend API client at frontend/src/api/client.js is a hub with 23 dependent modules and zero outgoing imports, making it a stable but high-churn integration point.
How To Use It
Setup: Clone the repository:
git clone https://github.com/moses-y/open-kritt
cd open-kritt
Install dependencies with npm install (root and backend/package.json, engine/pyproject.toml) and set environment variables from backend/.env.example and .env.example. Required keys include model provider API keys (OpenAI, Anthropic, OpenRouter) or a Codex login.
Configuration: Copy backend/.env.example to .env and populate ANTHROPIC_API_KEY, OPENAI_API_KEY, or CODEX_AUTH. The frontend references backend/src/api/client.js for API calls. Database migrations use backend/prisma/schema.prisma.
Running it: Start the full stack:
./kritt setup
./kritt start
Open http://localhost:5173 once running. For headless operation (no browser), use ./kritt-headless which imports portable workflow, post-script, skill, and ranker JSON and creates scans via the same backend validation.
Real-World Use
A security team wants to scan a private GitHub repository for injection vulnerabilities. They connect their GitHub token (optional, for private repos), select a model provider via ./kritt setup, and define a focused workflow in the UI that chains prompts for detecting specific issue types. The scan runs across the engine's worker architecture, producing findings that pass through post-scripts for validation. The team exports the results ZIP, which contains canonical findings, structured data, and proofs of concept – with attacker-influenced source kept as plain text for audit. Custom severity rankers from backend/src/lib/defaultSeverityRankers.js prioritize issues for triage.
Code Health & Issues
The static analysis identified 107 findings across 7 kinds, plus 11 code health audit findings:
- [HIGH] Pin third-party GitHub Actions to a commit SHA –
.github/workflows/release.ymlusesgoogleapis/release-please-action@v5; a tag can move, so the action running with secrets is unpredictable. - [HIGH] Commit a lockfile beside the manifest –
docs-site/package.jsonhas no lockfile; unlocked ranges risk shipping different transitive code. - [HIGH] Drop privileged mode and host networking –
docker-compose.ymlmounts the docker socket and uses host networking; privileged mode enables container escape with a one-liner. - [HIGH] Replace the wildcard CORS origin –
backend/src/app.jshasorigin: '*'combined with credentials, allowing any site to make authenticated requests. - [HIGH] Use bound parameters instead of building the SQL string –
executor-view/server.pyinterpolates user input directly into.execute()calls. - [MEDIUM] Pin the container base image by digest –
backend/Dockerfileusesnode:24.1.0-alpine3.20without a digest, allowing base image changes between builds. - [MEDIUM] Gate pull requests on a dependency vulnerability scan – CI has no dependency review action.
- [MEDIUM] Give the outbound request a timeout –
executor-view/server.pyhas 5 outbound calls with no timeout. - [MEDIUM] Set persist-credentials: false on checkout –
.github/workflows/ci.ymlkeeps the token for later steps. - [MEDIUM] Give the outbound request a timeout –
executor-view/server.pyhas 5 outbound calls with no timeout. - [LOW] Add a non-root USER to the image –
backend/Dockerfilehas no USER directive; process runs as root.
Beyond these, the measured analysis found 22 files with deep nesting (max indentation depth 8), 13 oversized files (940+ lines), 14 files with high branching density, and 7 hub modules with high blast-radius churn.
The Bottom Line
open·kritt delivers a practical, self-hosted platform for AI-agent-driven vulnerability research, with a clear task-orchestration model and export workflow that translates into real bug-bounty findings. The codebase shows structural maturity – tests, CI, lockfiles, and a license are present – but several high-severity SDLC gaps exist: wildcard CORS, und pinned Actions, privileged Docker containers, and SQL interpolation in executor-view. Teams that can manage the Docker and credential configuration will find it a capable framework; those needing the lowest operational friction should weigh the security hygiene gaps against the project's research value.