Multi-domain code quality gate for AI-generated apps. Security scanning, linting, SAST, SCA, IaC, container, testing, coverage, and duplication detection.
Project description
security-scan
Built by the Nometria team. We help developers take apps built with AI tools (Lovable, Bolt, Base44, Replit) to production — handling deployment to AWS, security, scaling, and giving you full code ownership. Learn more →
Multi-domain code quality gate for AI-generated web apps.
AI code generators (Lovable, Bolt, v0, Cursor, Copilot) frequently produce code with hardcoded secrets, missing auth guards, SQL injection patterns, and CORS misconfigs. This scanner catches those before they hit production — plus linting, SAST, SCA, and more.
Zero dependencies for core security rules. Pure Python stdlib.
Quick start
pip install -e .
# One-command setup (generates config + Claude Code integration)
security-scan init
# Scan your project
security-scan .
# Scan and auto-fix lint issues
security-scan . --fix
Commands
| Command | What it does |
|---|---|
security-scan . |
Scan the current directory |
security-scan init |
Generate config, .mcp.json, and .claude/CLAUDE.md |
security-scan doctor |
Validate environment (config, tools, MCP) |
security-scan serve |
Start MCP stdio server for Claude Code |
security-scan tools list |
Show managed tool status |
security-scan tools install trivy |
Download a managed tool binary |
CLI flags
security-scan [PATH] [OPTIONS]
Options:
--format {console,json,sarif,markdown} Output format (default: console)
--output FILE Write output to file
--fail-on LEVEL Exit 1 at this severity: critical, high, medium, low (default: high)
--mode {full,incremental,pr} Scan mode (default: full)
--base-ref REF Base branch for PR mode (default: auto-detect)
--domains DOMAIN,... Comma-separated domains to run (default: all available)
--fix Auto-fix lint issues (ruff, eslint)
--dashboard Generate QUALITY.md report
--watch Watch for file changes and re-scan
--config FILE Config file path
--strict Missing tools are findings
--no-color Disable ANSI colors
Security rules (SEC-001 — SEC-012)
| Rule | Severity | Catches |
|---|---|---|
| SEC-001 | CRITICAL | Hardcoded API keys, tokens, passwords, JWT secrets |
| SEC-002 | HIGH | .env file committed without .gitignore entry |
| SEC-003 | HIGH | Dangerous eval() / exec() usage |
| SEC-004 | HIGH | SQL injection (string interpolation in queries) |
| SEC-005 | HIGH | Missing auth middleware on API routes (Express/FastAPI) |
| SEC-006 | MEDIUM | CORS wildcard * in production code |
| SEC-007 | LOW | HTTP (not HTTPS) hardcoded URLs |
| SEC-008 | HIGH | Exposed admin routes without auth |
| SEC-009 | HIGH | Auth tokens stored in localStorage (XSS risk) |
| SEC-010 | MEDIUM | process.env values logged to console |
| SEC-011 | CRITICAL | Supabase service_role key used client-side |
| SEC-012 | MEDIUM | Dependency confusion risk in package.json |
Scan domains
Beyond the built-in security rules, the scanner can invoke external tools:
| Domain | Tools | What it checks |
|---|---|---|
| security | built-in (always available) | 12 regex rules (SEC-001 — SEC-012) |
| lint | Ruff, ESLint, Biome, Clippy, GoLangCI-Lint | Code style and logic errors |
| typecheck | MyPy, Pyright, tsc | Static type errors |
| sast | OpenGrep / Semgrep | Security vulnerabilities via SAST rules |
| sca | Trivy | Dependency CVE scanning |
| iac | Checkov | Infrastructure-as-code misconfigurations |
| container | Trivy | Dockerfile misconfigurations |
Domains auto-detect which tools are installed. Missing tools are silently skipped
(or flagged with --strict).
# Run only security + lint
security-scan . --domains security,lint
# Run everything available
security-scan .
Claude Code / MCP integration
The scanner integrates with Claude Code via the Model Context Protocol.
# One-time setup
security-scan init
# This generates:
# ai-security-scan.yml — scan configuration
# .mcp.json — tells Claude Code to use our MCP server
# .claude/CLAUDE.md — instructions for Claude
After init, restart Claude Code. Claude can then:
- Run
scanto check the project - Run
scan_fileto check a single file - Run
explainto get details on a finding - Run
statusto see available domains and tools
Configuration
Create ai-security-scan.yml in your project root (or run security-scan init):
# Which domains to run (empty = all available)
domains: [security, lint, sca]
# Scan mode: full | incremental | pr
scan_mode: full
# Fail threshold: critical | high | medium | low
fail_on: high
# Generate QUALITY.md dashboard
dashboard: false
# Auto-fix lint issues on scan
fix: false
# Directories to skip
exclude_patterns:
- node_modules
- .git
- dist
- build
# Per-domain tool config
tool_overrides:
lint:
ruff:
select: [E, F, W]
GitHub Action
name: Security Scan
on: [push, pull_request]
permissions:
contents: read
security-events: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nometria/security-scanner@main
with:
target_dir: '.'
fail_on: 'high'
sarif_upload: 'true'
Or install directly:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- run: pip install ai-security-scan
- run: security-scan . --format sarif --output results.sarif --fail-on high
- uses: github/codeql-action/upload-sarif@v3
if: always()
with: { sarif_file: results.sarif }
Use as a library
from security_scanner import scan_project, scan_project_v2
# Simple: built-in security rules only
result = scan_project("./my-app")
print(f"Passed: {result.passed}, Findings: {len(result.findings)}")
# Multi-domain: security + lint + sca + any installed tools
result = scan_project_v2("./my-app")
for name, info in result.domain_results.items():
print(f" {name}: {info['findings']} findings ({info['time']:.1f}s)")
Project structure
src/security_scanner/
├── scanner.py # Core: 12 security rules + scan_project + scan_project_v2
├── cli.py # CLI: scan, init, doctor, serve, tools
├── config.py # YAML config loader
├── reporter.py # Output: console, JSON, SARIF, Markdown
├── detection.py # Language/framework auto-detection
├── dashboard.py # QUALITY.md generator
├── history.py # Quality trending + health scores
├── git_utils.py # Git diff/branch utilities
├── mcp.py # MCP tool library (Python API)
├── mcp_server.py # MCP stdio server (for Claude Code)
├── domains/
│ ├── builtin.py # Wraps the 12 SEC rules as a domain
│ ├── lint.py # Ruff, ESLint, Biome, Clippy, GoLangCI-Lint
│ ├── typecheck.py # MyPy, Pyright, tsc
│ ├── sast.py # OpenGrep / Semgrep
│ ├── sca.py # Trivy (dependency vulnerabilities)
│ ├── iac.py # Checkov (IaC misconfigs)
│ └── container.py # Trivy (Dockerfile misconfigs)
├── provisioning/ # Managed tool download + verification
└── agents/ # Diff analysis + finding review (optional)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ai_security_scan-0.3.0.tar.gz.
File metadata
- Download URL: ai_security_scan-0.3.0.tar.gz
- Upload date:
- Size: 56.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10c2e48366eb9bff3742eff14e8da37cd65259b7da36244944f0c5b573744d40
|
|
| MD5 |
979d71c7571f9deb92bc974a63153b9c
|
|
| BLAKE2b-256 |
39987e9067aabc4b98eb71c4b141111249ad35e9856df7b68f2aa9a211fc2231
|
File details
Details for the file ai_security_scan-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ai_security_scan-0.3.0-py3-none-any.whl
- Upload date:
- Size: 62.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b871fa31f41eeb1e6bc551f172a0089398d772c4e41ba0b920c52d5a1bb94ecd
|
|
| MD5 |
3fa33b1ccf4dbf15b31347eb8e4c9e71
|
|
| BLAKE2b-256 |
cca9f169819748ca32148e8be7856f69a3f6607ac0b928ce22e67ce3f81dd47c
|