Deploy, Test & Pen-Test in Isolated Sandboxes
A self-learning, self-adaptive security-first deployment platform with autonomous security scanning, AI-assisted attack pipelines, and real-time monitoring.
- Project Overview
- Core Features
- Attack Pipeline
- Security Testing Suite
- Architecture
- Tech Stack
- Console Dashboard
- Database Schema
- API Reference
- Environment Variables
- Custom Runtime Template
- Installation Guide
- Contributing & GSSoC
- Project File Structure
- Security Architecture Highlights
- Scoring Model
SecDev is a cloud-native autonomous deployment platform that enables developers to deploy any Git repository into isolated E2B sandbox environments with one click, then immediately run comprehensive security, performance, and penetration tests against the live deployment.
"One-click deployment meets autonomous pen-testing. Zero DevOps configuration required."
What makes SecDev different:
- Every deployment is automatically testable β get a real security score before your app reaches production
- AI-assisted attack pipeline discovers vulnerabilities using SQL injection, auth bypass, command injection, and parameter manipulation agents
- All test results are persisted per-user in PostgreSQL β full history with re-loadable reports
- Live terminal streaming for all operations β see exactly what's running in real time
- Stop any scan mid-flight with a single button click
- Connects to your GitHub account via OAuth
- Fetches all public and private repositories
- Detects framework automatically: Next.js, Vite, Express, Create React App, Static HTML
- Detects package manager automatically: pnpm / yarn / npm
- Adaptive memory management β uses
next devinstead ofnext buildto avoid OOM crashes in 1 GB sandboxes - Streams all build and server logs in real time to the dashboard
- Provides a public preview URL for every deployment
- Auto-destroys sandbox after 1 hour (configurable)
- Add, view, update, and delete per-deployment environment variables
- Automatic AES-256-GCM encryption at rest
- Random IV per value β same plaintext encrypts differently every time
- UI shows masked values (
****abcβ last 4 chars visible) - Secrets injected into sandbox at deployment time, never written to disk in plaintext
- Lists all repos (public + private) from authenticated GitHub account
- Shows visibility, fork status, language, star count, last updated
- Supports table and card view modes
- One-click deploy from within the repo browser
- Every line from every deployment (stdout + stderr) is inserted into
deployment_logs - Dashboard auto-refreshes every 5 seconds
- Color-coded:
errorlines in red,infolines in normal text - Filterable by sandbox ID
- All data (deployments, logs, test runs, secrets, scans) is strictly scoped to
user_id - No cross-user data leakage at the API or database level
- Session-based auth via NextAuth (GitHub OAuth) + Firebase (email / Google)
- Free / Pro / Enterprise plan UI
- Current plan indicator with usage breakdown
- Upgrade / downgrade flow (UI-ready)
The crown feature of SecDev β a modular, AI-assisted penetration testing pipeline that runs against any URL (your E2B deployment or any external target you own).
Target URL
β
βΌ
βββββββββββββββββββββββββββββββββββ
β Route Discovery (routeParser) β β Probes common paths, crawls links
ββββββββββββββββββ¬βββββββββββββββββ
β discovered routes
ββββββββββββββΌβββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββ ββββββββββββ ββββββββββββ ββββββββββββ
β SQL β β Auth β βInjection β βParameter β
βInject β β Bypass β β Agent β β Agent β
βββββ¬ββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ
ββββββββββββββ΄ββββββββββββββ΄ββββββββββββββ
β findings
βΌ
βββββββββββββββββββββββββββ
β Security Scanner β β Vibetest (fuzz), API validation, scoring
ββββββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββββββ
β Performance Scanner β β 50 req Γ 10 concurrent, p95/p99 latency
ββββββββββββββ¬βββββββββββββ (optional, enable in UI)
β
βΌ
βββββββββββββββββββββββββββ
β AI Analysis (Groq) β β llama-3.1-8b-instant summarizes findings,
ββββββββββββββ¬βββββββββββββ ranks risks, gives remediation steps
β
βΌ
VulnerabilityReport β Stored as JSON in DB, reloadable from history
| Agent | Checks | Techniques |
|---|---|---|
| SQL Injection | 4 strategies | Error-based, blind boolean, time-based, UNION exfiltration |
| Auth Bypass | JWT manipulation, default creds, mass assignment, forced browsing | alg: none, weak secrets, IDOR on user IDs |
| Injection | Command injection, SSTI, path traversal, CRLF | ; cat /etc/passwd, {{7*7}}, ../../etc/passwd, \r\nHeader: |
| Parameter | Privilege escalation, HTTP parameter pollution, type confusion, prototype pollution | ?admin=true, ?id[]=1&id[]=2, {"__proto__":{}} |
- 130+ built-in payloads across all attack categories
- SQL payloads: error-based, union, blind boolean, time-based
- Auth payloads: default credentials, JWT manipulation payloads, IDOR IDs
- Injection payloads: shell commands, SSTI probes, path traversal chains, CRLF sequences
- Parameter payloads: type confusion, mass assignment, prototype pollution objects
- Fuzz payloads: boundary values, null bytes, oversized inputs, special chars
- AI payload augmentation via Groq β generates target-specific payload variations based on app behavior (when enabled)
| Feature | Description |
|---|---|
| Target selector | Toggle between E2B deployment dropdown and custom URL input |
| AI Analysis toggle | Enable/disable Groq llama-3.1-8b-instant analysis |
| Performance toggle | Enable/disable 50 req Γ 10 concurrent load test |
| Run Attack button | Starts scan and immediately switches to a Stop button |
| Stop button | Aborts the SSE stream client-side; sends PATCH to DB to mark run as stopped |
| Live terminal | Real-time SSE log stream with green-on-black mono font, auto-scroll |
| Score gauge | SVG arc gauge (0β100) color-coded: green β₯ 85, yellow β₯ 65, orange β₯ 45, red < 45 |
| Severity cards | Critical / High / Medium / Low / Passed / Total count tiles |
| AI Analysis panel | Summary, key findings list, and remediation recommendations from Groq |
| Findings tab | Grouped by agent, collapsible sections; each finding shows severity badge, payload, curl replay command with copy button, and remediation advice |
| Vibetest tab | Fuzz test results table with route, test case, status, and evidence |
| Coverage tab | Route grid: red = issues found, green = clean, gray = untested |
| Performance tab | Per-route avg latency, p95 latency, req/s, success rate, and pass/fail status |
| History section | All past runs with date, URL, score, risk badge, and status β click any completed run to reload its full report |
lib/attack-pipeline/
βββ pipeline/
β βββ runScan.ts β Entry point: 4-step pipeline orchestrator
βββ agents/
β βββ sqlInjectionAgent.ts β SQL injection (4 strategies)
β βββ authBypassAgent.ts β Auth bypass (JWT, default creds, IDOR)
β βββ injectionAgent.ts β CMD/SSTI/path traversal/CRLF
β βββ parameterAgent.ts β HPP, type confusion, prototype pollution
β βββ orchestrator.ts β Routes β agent assignment β batched execution
βββ scanners/
β βββ securityScanner.ts β Orchestrator + vibetest + API validation + scoring
β βββ performanceScanner.ts β Load test: p50/p95/p99 latency per route
βββ parsers/
β βββ routeParser.ts β Route discovery via HTTP probing + link crawling
βββ utils/
βββ httpClient.ts β Stateful HTTP client with session cookie jar
βββ payloadGenerator.ts β 130+ payloads + AI augmentation via Groq
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/attack-pipeline |
Start scan β returns text/event-stream SSE |
GET |
/api/attack-pipeline |
List user's attack pipeline runs (last 30) |
PATCH |
/api/attack-pipeline |
Stop a running scan { runId } β status stopped |
GET |
/api/attack-pipeline/report?runId= |
Fetch full VulnerabilityReport for a completed run |
In addition to the Attack Pipeline, SecDev has a full Playwright-based security testing system powered by Inngest background functions.
| Page | URL | What It Tests |
|---|---|---|
| Security Scans | /console/security |
Playwright: XSS, security headers, HTTPS enforcement, clickjacking, cookie security |
| AI Security Agent | /console/security (Agent tab) |
Inngest-powered AI agent that analyzes app behavior and generates findings |
| E2E Tests | /console/e2e |
Playwright end-to-end user journey tests inside E2B sandbox |
| API Testing | /console/api-testing |
HTTP request builder: method, headers, body, response inspection |
| Load Testing | /console/load |
Configurable concurrent user simulation with latency tracking |
| Visual Testing | /console/visual |
Screenshots + visual diff via Playwright |
| Attack Pipeline | /console/attack-pipeline |
Full penetration test pipeline (see above) |
All test pages share the same UX pattern:
- Deployment dropdown (select active E2B sandbox) or custom URL input toggle
- Run / Stop controls
- Live terminal with real-time SSE log streaming
- History section always visible (even when 0 runs exist)
- Status badges:
running/completed/failed/stopped - Click any completed run in history to reload full results
| Function | Trigger | What It Does |
|---|---|---|
run-security-scan |
POST /api/security-agent/run |
Spawns E2B sandbox β installs Playwright β runs security checks β AI analysis β writes logs to DB |
run-e2e-tests |
POST /api/tests/run |
Browser automation β screenshot capture β test assertions |
run-load-test |
POST /api/tests/run |
Concurrent HTTP bombardment β latency aggregation |
run-visual-test |
POST /api/tests/run |
Puppeteer screenshots β pixel diff comparison |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser (Next.js) β
β β
β Public Pages Auth Console (/console/*) β
β /, /login, Firebase + ββββββββββββββββββββββββββββ β
β /register NextAuth β Sidebar Navigation β β
β β β Overview β β
β β β Deployments β β
β β β Repositories β β
β β Testing: β β
β β β Security β β
β β β E2E Tests β β
β β β API Testing β β
β β β Load Testing β β
β β β Visual Testing β β
β β β Attack Pipeline β β
β β Settings: β β
β β β Secrets β β
β β β Billing β β
β ββββββββββββββββββββββββββββ β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββ
β
API Routes (/api/*)
β
ββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
β API Layer β
β β
β /api/deploy Deployment CRUD + logs β
β /api/repos GitHub repo list β
β /api/secrets Encrypted env vars CRUD β
β /api/security-agent Inngest workflow trigger β
β /api/tests/run Generic test runner + stop β
β /api/attack-pipeline Attack pipeline SSE + CRUD β
β /api/attack-pipeline/report Fetch full report β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
β Infrastructure β
β β
β Neon PostgreSQL E2B Sandboxes Inngest β
β (all user data) (isolated VMs) (workflows) β
β β
β Groq AI GitHub API Firebase Auth β
β (analysis) (repo list) (user auth) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
User clicks Deploy
β
βΌ
POST /api/deploy
β
βββ Create E2B sandbox (~3s)
βββ Insert deployment record (status: "deploying")
βββ Start background pipeline (fire-and-forget)
β
βββ Clone Git repo (shallow, depth 1)
βββ Detect package manager (pnpm/yarn/npm)
βββ Install dependencies
β βββ Inject encrypted env vars as process.env
βββ Detect framework from package.json scripts
β βββ "next" β Next.js (use next dev, memory-safe)
β βββ "vite" β Vite (npm run dev)
β βββ "react-scripts" β CRA (npm start)
β βββ "node" / other β direct node execution
βββ Start server process
β βββ stream every stdout/stderr line β deployment_logs
βββ Update status: deploying β live / failed
| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js 15 (App Router) | SSR, API routes, React Server Components |
| Language | TypeScript 5 | Full-stack type safety |
| Styling | Tailwind CSS 4 | Utility-first responsive dark/light UI |
| Auth | Firebase Auth + NextAuth 5 | Email/Google (Firebase) + GitHub OAuth (NextAuth) |
| Database | Neon PostgreSQL (serverless) | All user data, logs, test results, reports |
| Sandboxes | E2B | Isolated Linux microVMs per deployment |
| Workflows | Inngest | Durable background functions for long-running scans |
| AI | Groq (llama-3.1-8b-instant) |
Payload augmentation + vulnerability analysis |
| Streaming | Web Streams API (SSE) | Real-time log delivery to browser |
| Encryption | Node.js crypto AES-256-GCM |
Env var encryption at rest with random IV |
| Icons | Lucide React | Consistent icon library across all UI |
Console
βββ Overview β Active deployments summary, quick stats
βββ Testing
β βββ Security β Playwright security checks + Inngest AI agent
β βββ E2E Tests β Browser automation end-to-end tests
β βββ API Testing β HTTP request builder and tester
β βββ Load Testing β Concurrent user performance benchmarking
β βββ Visual Testing β Screenshot capture and visual diff
β βββ Attack Pipeline β Full AI-assisted penetration test pipeline
βββ Settings
βββ Repositories β GitHub repository browser (card + table view)
βββ Deployments β All deployments with logs and status
βββ Secrets β Encrypted environment variable manager
βββ Billing β Plan selection (Free / Pro / Enterprise)
All tables are created automatically on first request via ensureTables() in lib/db.ts.
Current schema version: 4
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
repo_name TEXT,
repo_url TEXT,
branch TEXT,
sandbox_id TEXT,
public_url TEXT,
status TEXT, -- deploying | live | failed | terminated
created_at BIGINT,
updated_at BIGINT,
framework TEXT,
error TEXTid BIGSERIAL PRIMARY KEY,
sandbox_id TEXT NOT NULL,
ts BIGINT NOT NULL,
level TEXT NOT NULL, -- info | error
msg TEXT NOT NULLid TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
sandbox_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL, -- AES-256-GCM: "iv:tag:ciphertext" (hex)
created_at BIGINTid TEXT PRIMARY KEY,
user_id TEXT NOT NULL DEFAULT '',
sandbox_id TEXT NOT NULL,
test_type TEXT NOT NULL,
status TEXT NOT NULL, -- running | completed | failed | stopped
created_at BIGINT NOT NULL,
finished_at BIGINT,
result_json TEXT -- full test result serialized as JSONid TEXT PRIMARY KEY,
user_id TEXT NOT NULL DEFAULT '',
base_url TEXT NOT NULL,
sandbox_id TEXT,
status TEXT NOT NULL DEFAULT 'running', -- running | completed | failed | stopped
created_at BIGINT NOT NULL,
finished_at BIGINT,
routes_found INT DEFAULT 0,
overall_score INT, -- 0β100 security score
risk_level TEXT, -- Minimal | Low | Medium | High | Critical
critical_count INT DEFAULT 0,
high_count INT DEFAULT 0,
medium_count INT DEFAULT 0,
low_count INT DEFAULT 0,
passed_count INT DEFAULT 0,
summary TEXT, -- AI-generated one-liner summary
report_json TEXT -- full VulnerabilityReport as JSON| Method | Endpoint | Description |
|---|---|---|
GET |
/api/deploy |
List user's deployments |
POST |
/api/deploy |
Create new deployment from Git URL |
DELETE |
/api/deploy/[id] |
Stop and remove deployment + sandbox |
GET |
/api/deploy/logs?sandboxId= |
Get logs for a deployment |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/repos |
List GitHub repos for authenticated user |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/secrets?sandboxId= |
List secrets for a sandbox |
POST |
/api/secrets |
Create and encrypt a secret |
PUT |
/api/secrets/[id] |
Update secret value |
DELETE |
/api/secrets/[id] |
Delete a secret |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/security-agent/run |
Trigger Inngest security scan workflow |
GET |
/api/tests/run |
List test runs for current user |
POST |
/api/tests/run |
Start a test run (E2E / load / visual / API) |
POST |
/api/tests/stop |
Stop an in-progress test run |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/attack-pipeline |
Start scan β returns text/event-stream SSE response |
GET |
/api/attack-pipeline |
List user's attack pipeline runs (last 30, newest first) |
PATCH |
/api/attack-pipeline |
Stop a running scan: { runId: "ap_..." } |
GET |
/api/attack-pipeline/report?runId=ap_... |
Fetch full VulnerabilityReport JSON for a run |
{
"baseUrl": "https://my-app.example.com", // required
"sandboxId": "sandbox_abc", // optional, associates run with deployment
"useAi": true, // enable Groq AI analysis
"includePerformance": false, // enable load test
}# ββ Authentication ββββββββββββββββββββββββββββββββββββββββββββββββ
NEXTAUTH_SECRET= # Random 32+ char secret for NextAuth JWT signing
NEXTAUTH_URL= # App base URL (e.g. http://localhost:3000)
# GitHub OAuth (NextAuth provider)
GITHUB_CLIENT_ID= # GitHub OAuth App client ID
GITHUB_CLIENT_SECRET= # GitHub OAuth App client secret
# Firebase (Email / Google auth)
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
# ββ Database ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DATABASE_URL= # Neon PostgreSQL pooled connection string
# ββ E2B (Sandbox runtime) βββββββββββββββββββββββββββββββββββββββββ
E2B_API_KEY= # E2B API key for creating/managing sandboxes
# ββ Inngest (Workflow engine) βββββββββββββββββββββββββββββββββββββ
INNGEST_EVENT_KEY= # Inngest event signing key
INNGEST_SIGNING_KEY= # Inngest webhook signing key
# ββ AI (Attack Pipeline) βββββββββββββββββββββββββββββββββββββββββ
GROQ_API_KEY= # Groq API key for llama-3.1-8b-instant
# ββ Encryption βββββββββββββββββββββββββββββββββββββββββββββββββββ
ENCRYPTION_KEY= # 32-byte hex string (64 hex chars) for AES-256-GCMSecDev uses a custom E2B sandbox template (secdev-web-runtime) pre-installed with:
- Node.js 20 LTS with npm, yarn, pnpm
- Playwright with Chromium browser for automated tests
- Git, curl, wget, python3 for build tools
- Pre-warmed dependency cache to speed up installs
Template location: templates/web-runtime/
Build and publish the template:
cd templates/web-runtime
e2b template build --name secdev-web-runtime- Node.js 20+
- pnpm (recommended) or npm
- Neon PostgreSQL database (free tier works)
- E2B account + API key
- GitHub OAuth App (for repo access)
- Firebase project (for email / Google auth)
- Groq API key (for AI features β free tier available)
- Inngest account (for background workflows β free tier available)
# 1. Clone the repository
git clone https://github.com/your-org/secdev.git
cd secdev
# 2. Install dependencies
pnpm install
# 3. Copy and fill environment variables
cp .env.example .env
# Edit .env with your keys
# 4. Start development server
pnpm dev
# 5. Start Inngest dev server (separate terminal)
npx inngest-cli@latest devpnpm build
pnpm startIf you want to contribute to SecDev, start with these project-specific docs:
- CONTRIBUTING.md - setup, branch naming, PR flow, and code style
- CONTRIBUTING_GUIDE_GSSOC.md - GSSoC issue claiming and mentor workflow
- GOOD_FIRST_ISSUE.md - beginner-friendly issues tailored to this repo
- CODE_OF_CONDUCT.md - community behavior expectations
For GitHub issue and PR flows, also use the built-in templates in .github/ISSUE_TEMPLATE and .github/PULL_REQUEST_TEMPLATE.md.
secdev/
βββ app/
β βββ page.tsx Landing / marketing page
β βββ login/page.tsx Firebase email/Google login
β βββ register/page.tsx Firebase registration
β βββ globals.css Global styles
β βββ console/
β βββ layout.tsx Console shell (sidebar + top bar)
β βββ page.tsx Overview dashboard
β βββ deployments/page.tsx Deployment management
β βββ repositories/page.tsx GitHub repo browser
β βββ security/page.tsx Security scans + AI agent tabs
β βββ security-agent/page.tsx Redirects to /console/security
β βββ e2e/page.tsx End-to-end test runner
β βββ api-testing/page.tsx API request builder
β βββ load/page.tsx Load / performance test runner
β βββ visual/page.tsx Visual / screenshot tester
β βββ attack-pipeline/page.tsx β Attack pipeline UI (full pen-test)
β βββ secrets/page.tsx Encrypted env var manager
β βββ billing/page.tsx Plan management
β
βββ app/api/
β βββ auth/[...nextauth]/ NextAuth route handler
β βββ deploy/ Deployment CRUD + log streaming
β βββ repos/ GitHub repos endpoint
β βββ secrets/ Encrypted secrets CRUD
β βββ security-agent/run/ Inngest security scan trigger
β βββ tests/run/ Generic test runner
β βββ tests/stop/ Stop a running test
β βββ attack-pipeline/
β βββ route.ts POST (start scan SSE) / GET (list) / PATCH (stop)
β βββ report/route.ts GET full report by runId
β
βββ components/
β βββ console/
β βββ sidebar.tsx Sidebar nav (all routes + icons)
β βββ repository-card.tsx Repo card component
β βββ repository-table.tsx Repo table component
β
βββ lib/
β βββ auth.ts NextAuth config (GitHub provider)
β βββ db.ts Neon DB client + ensureTables() (schema v4)
β βββ crypto.ts AES-256-GCM encrypt/decrypt helpers
β βββ attack-pipeline/ β Modular pen-test engine
β βββ pipeline/runScan.ts Entry point: orchestrates all 4 steps
β βββ agents/
β β βββ sqlInjectionAgent.ts
β β βββ authBypassAgent.ts
β β βββ injectionAgent.ts
β β βββ parameterAgent.ts
β β βββ orchestrator.ts
β βββ scanners/
β β βββ securityScanner.ts
β β βββ performanceScanner.ts
β βββ parsers/
β β βββ routeParser.ts
β βββ utils/
β βββ httpClient.ts
β βββ payloadGenerator.ts
β
βββ inngest/ Inngest function definitions
βββ templates/web-runtime/ E2B custom sandbox template
βββ public/ Static assets
βββ next.config.ts Next.js config
βββ tsconfig.json TypeScript config
βββ eslint.config.mjs ESLint config
| Concern | Implementation |
|---|---|
| Sandbox isolation | Every deployment gets its own E2B microVM β code cannot escape or reach other users |
| Secret encryption | AES-256-GCM with a fresh random IV per value β DB breach does not expose secrets |
| Multi-tenancy | Every API route checks session.user.id; all DB queries filter by user_id |
| URL validation | Attack pipeline validates ^https?:// before issuing any HTTP requests |
| Auth on every route | Every API handler returns 401 before any logic if session is missing |
| Attack scope | Penetration tests only run against explicitly provided target URLs |
| Stop support | Client can abort SSE stream anytime; PATCH endpoint marks the run as stopped in DB |
| OWASP mitigations | Parameterized SQL via tagged template literals (Neon) prevents SQL injection in the platform itself |
The overall security score (0β100) is computed by the securityScanner:
base_score = 100
Deductions per finding:
critical β -20
high β -10
medium β -5
low β -2
Score is clamped to minimum 0.
Risk level bands:
β₯ 85 β Minimal
β₯ 65 β Low
β₯ 45 β Medium
β₯ 25 β High
< 25 β Critical
The score is:
- Displayed in the SVG arc gauge on the report page
- Stored in
attack_pipeline_runs.overall_score - Shown as a colored number in the history list
- Used to determine the risk level badge color
Built with Next.js Β· E2B Β· Neon PostgreSQL Β· Inngest Β· Groq Β· TypeScript


{ "type": "start", "runId": "ap_abc123", "baseUrl": "https://..." } { "type": "progress", "msg": "β Testing /api/login for SQL injection..." } { "type": "complete", "runId": "ap_abc123", "report": { /* VulnerabilityReport */ } } { "type": "error", "runId": "ap_abc123", "error": "Connection refused" }