wren-security
v2.11.2
Published
Security scanning for AI-generated code, from your terminal.
Maintainers
Readme
wren-security 🦅
Security scanning for AI-generated code, directly from your terminal.
Catch what Cursor, Lovable, Bolt, and v0 leave behind — before it reaches production.
Quick Start (Zero Install)
Run instantly against any directory with npx:
npx wren-security check .Or install globally:
npm install -g wren-security
wren-security checkWhy Wren?
AI code generators prioritize speed and making the UI work immediately. In doing so, they systematically leave critical security holes:
- Hardcoding secrets & API keys (
sk-...,sk_live_...) directly in source code. - Generating backend mutating endpoints (
POST,PUT,DELETE) without verifying authenticated user sessions. - Leaking admin credentials by prefixing server keys with
NEXT_PUBLIC_or using Supabase Service Role keys inside client components. - Defaulting database security rules to wide-open permissions (
allow read, write: if true;) so tests pass during prompting.
Wren scans your codebase in milliseconds, flags high-risk AI patterns, and outputs exact copy-paste code diffs to fix them.
Features
- ⚡ Zero-Config & Instant: Runs locally in sub-seconds. No heavy daemon, no remote code upload required.
- 🛡️ AI-Specific Static & AST Engine: Tailored heuristics targeting the signature mistakes of LLM-generated code.
- 🚦 CI/CD Built-In:
--fail-on-criticalreturns a non-zero exit code to automatically block dangerous PRs. - 📊 GitHub Code Scanning (SARIF 2.1.0): Export findings directly into GitHub's Security Tab.
- 🔒 Zero Data Retention: Your source code never leaves your machine. Local scanning is 100% offline.
- 💡 Actionable Remediations: Every finding includes a human-readable explanation, CWE reference, and an exact unified diff fix.
Commands & Usage
1. wren-security check [path] (or wren-security scan)
Scans your files for security vulnerabilities.
# Scan current directory
wren-security check
# Scan a specific folder
wren-security check ./src
# Exit with code 1 if critical vulnerabilities exist (perfect for CI/CD)
wren-security check --fail-on-critical
# Fail on high or critical issues
wren-security check --fail-on high
# Output as SARIF for GitHub Security Tab
wren-security check --format sarif -o results.sarif
# Output as machine-readable JSON
wren-security check --format json -o wren-report.json
# Asynchronous background scan with real-time status
wren-security check --async
# Enable Deep Reasoning Mode (agentic verification loop)
wren-security check --llmDeep Reasoning Mode (agentic-verification-loop)
"Wren now investigates before it reports — not just pattern-matches."
When --llm is enabled, Wren replaces simple one-shot evaluation with an autonomous investigative verification loop:
- 🔍 Multi-Turn Codebase Investigation: Wren explores callers, sanitizers, middleware, and route handlers before deciding if a finding is a genuine vulnerability or a mitigated false positive.
- 🛡️ Strictly Read-Only Guarantee: The agent is restricted to three read-only tools:
read_file(path): Inspects project files inside a strict path-traversal sandbox.search_codebase(pattern): Searches project files for patterns, sanitizers, and symbols.get_call_sites(function_name): Traces invocation call sites across the codebase. The agent can never write, mutate, execute, or delete code.
- ⏱️ Bounded Cost & Safe Fallback: Capped at a maximum of 5 tool calls per finding. If an ambiguous case cannot be concluded within 5 steps, Wren stops, marks the finding for manual review (
[Needs Manual Review]), and records complete trace diagnostics inagent_traces.
CLI Options:
| Flag | Type | Description | Default |
|---|---|---|---|
| [path] | string | Target directory to scan | . (current directory) |
| --async | boolean | Dispatch scan to background queue and stream progress | false |
| --fail-on-critical | boolean | Exit code 1 if critical findings are found | false |
| --fail-on <severity> | string | Exit code 1 if findings at or above threshold exist (critical, high, medium) | — |
| --format <format> | string | Output format: terminal, json, or sarif | terminal |
| --llm | boolean | Enrich findings with contextual LLM reasoning & agent loop | false |
| -o, --output <file> | string | Write report output directly to a file | stdout |
| --api-key <key> | string | Wren Cloud or Anthropic API key | — |
| -v, --version | boolean | Display version number | — |
| -h, --help | boolean | Show help and options | — |
2. wren-security fix [findingId]
Generates an AST syntax-verified remediation patch and applies it or dispatches a GitHub Pull Request:
# Preview proposed unified diff patch without touching disk
wren-security fix --dry-run
# Apply verified patch directly to local disk
wren-security fix --apply-locally
# Remediate a specific finding by ID
wren-security fix hardcoded-secret-abc123 --apply-locally
# Dispatch an isolated branch and Pull Request via GitHub App
wren-security fix --open-pr --repo owner/repoFix Options:
| Flag | Type | Description | Default |
|---|---|---|---|
| [findingId] | string | ID of the finding to remediate | First finding |
| --dry-run | boolean | Preview unified diff patch without writing to disk | false |
| --apply-locally | boolean | Apply verified patch directly to the target file on disk | false |
| --open-pr | boolean | Create a branch and open a GitHub Pull Request | false |
| --repo <owner/repo>| string | Target GitHub repository (auto-detected from git remote) | Local remote |
| --api-url <url> | string | Custom Wren Cloud API endpoint | http://localhost:3000 |
3. wren-security init
Initializes Wren configuration in your repository:
wren-security initCreates:
.wrenignore: Excludes test fixtures, mock data, or build directories..wrenrc.json: Configures failure thresholds and rule overrides.
4. wren-security login [token] & wren-security logout
Connect your CLI to your Wren Cloud dashboard:
# Interactive token prompt
wren-security login
# Or pass token directly
wren-security login <your-api-token>
# Remove stored credentials
wren-security logoutStored securely in ~/.wren/config.json (respects XDG_CONFIG_HOME).
Vulnerabilities Detected
| Rule ID | Category | Severity | Description | CWE |
|---|---|---|---|---|
| WREN-SEC-001 | Secret | Critical | Hardcoded OpenAI API key (sk-proj-..., sk-...) | CWE-798 |
| WREN-SEC-002 | Secret | Critical | Live Stripe secret key (sk_live_...) committed in source | CWE-798 |
| WREN-SEC-003 | Secret | Critical | Anthropic Claude API key (sk-ant-...) exposed | CWE-798 |
| WREN-SEC-004 | Secret | Critical | AWS Access Key ID (AKIA...) hardcoded | CWE-798 |
| WREN-SEC-005 | Secret | Critical | GitHub Personal Access Token (ghp_..., github_pat_...) | CWE-798 |
| WREN-DB-001 | Database | Critical | Database connection URI with embedded plaintext password | CWE-312 |
| WREN-SEC-006 | Secret | High | Secret variable leaked to browser bundle with NEXT_PUBLIC_ | CWE-200 |
| WREN-AUTH-001 | Auth | High | Mutating API route (route.ts) missing user authentication check | CWE-306 |
| WREN-AUTH-002 | Auth | Critical | Supabase Service Role key referenced in a client component | CWE-285 |
| WREN-DB-003 | Database | Critical | Firestore rules permitting unrestricted public read/write (if true;) | CWE-276 |
| WREN-CONF-001 | Config | Medium | Permissive wildcard CORS header (*) on API endpoints | CWE-346 |
GitHub Actions CI/CD Integration
Add Wren to your .github/workflows/security.yml to automatically scan every Pull Request:
name: Wren Security Scan
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
wren-scan:
runs-on: ubuntu-latest
permissions:
security-events: write # Required for SARIF upload
contents: read
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Run Wren Security Check
run: npx wren-security check . --format sarif -o results.sarif --fail-on-critical
- name: Upload SARIF to GitHub Security Tab
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarifProgrammatic Node.js API
You can also use Wren programmatically inside Node.js or build scripts:
import { runScan } from "wren-security";
async function audit() {
const result = await runScan({
targetPath: "./src",
failOnSeverity: "critical",
});
console.log(`Scanned ${result.summary.filesScanned} files.`);
console.log(`Total Findings: ${result.summary.totalFindings}`);
for (const finding of result.findings) {
console.log(`[${finding.severity.toUpperCase()}] ${finding.title}`);
console.log(` File: ${finding.location.filePath}:${finding.location.startLine}`);
console.log(` Fix: ${finding.fix.description}`);
}
}
audit();Configuration (.wrenrc.json)
{
"$schema": "https://wren.dev/schema.json",
"version": 1,
"failOn": "critical",
"ignoreRules": [
"WREN-CONF-001"
],
"ignorePaths": [
"fixtures/**",
"**/*.test.ts"
]
}Security & Privacy Policy
- 100% Local Execution: Source code is parsed and analyzed locally on your machine.
- Zero Telemetry Leaks: Code snippets are never transmitted to external analytics.
Contributing & Issues
- Issues & Feature Requests: GitHub Issues
- Web Platform & Docs: https://wren.dev
License
MIT © Wren Security
