OpenSecurity is an open-source CLI that scans entire repositories for security risks across application code, infrastructure/config files, and dependencies. It combines fast local analysis with optional AI scanning to keep coverage broad but practical.
OpenSecurity combines JS/TS native AST+taint, Tree‑sitter native taint for Python/Go/Java/C#/Ruby/PHP/Rust/Kotlin/Swift/C/C++ (scoped taint + sanitizer tracking), optional external adapters (Bandit, gosec, Brakeman, Semgrep), infra/config patterns (Dockerfile, Kubernetes/Helm, Terraform, YAML), dependency CVE scanning (npm/PyPI), and optional AI scanning across text files (--no-ai to disable). Universal patterns are heuristic (fast but shallow). Native AST/taint is a baseline multi‑lang engine and does not replace deep, language‑specific SAST.
- This tool is not a full SAST replacement or compliance scanner.
- It does not execute or sandbox code.
- It does not guarantee complete coverage of all vulnerabilities.
- It does not replace specialized commercial scanners (e.g., Codex Security, Claude Security).
- For compliance-grade coverage, use dedicated SAST/compliance tooling.
- Use it as a complementary signal, not a single source of truth.
Node.js 20+ is required.
npm i opensecurityPackage: https://www.npmjs.com/package/opensecurity
No build step is required when installing from npm.
- Configure API key (optional, only if you want AI scanning):
opensecurity login --mode api_key --provider openai- Run a scan:
opensecurity scan- Common options:
opensecurity scan --diff-only
opensecurity scan --no-ai
opensecurity scan --provider anthropic --model claude-sonnet-4-20250514If no API key is configured, AI scanning is skipped automatically.
If you only want local scanning, you can skip login and run opensecurity scan --no-ai.
- Node.js 20+ is required.
- macOS, Linux, Windows
- AST taint engine with configurable sources/sinks/sanitizers (JS/TS + native multi‑lang).
- OWASP-aligned default rules (SQLi, command injection, SSRF, path traversal, template XSS, deserialization).
- Pattern-based detectors (hardcoded secrets, insecure crypto, unsafe deserialization).
- Optional external adapters for top languages (Bandit, gosec, Brakeman, Semgrep).
- Dependency scanning for npm and PyPI (
package.json,package-lock.json,requirements.txt). - Text, JSON, and SARIF output.
- Optional AI scan (API key or OAuth flow) with multiple providers.
- Configurable include/exclude filters and scan scope.
-
File discovery
- Walks the repository based on
include/exclude. - Optional
--diff-onlyor--pathto narrow scope.
- Walks the repository based on
-
Static analysis (JS/TS)
- Parses JS/TS with Babel and runs taint rules (sources → sinks → sanitizers).
- Emits OWASP-aligned findings.
-
Pattern detectors (JS/TS)
- Finds hardcoded secrets, insecure crypto, and unsafe deserialization.
-
AI scan (all text files by default)
- Splits files into chunks and sends to the configured model.
- Optional multi‑agent batching with shared leader context.
- Optional per‑file cache to skip unchanged files.
-
Native AST/taint (Tree‑sitter)
- Loads Tree‑sitter parsers (WASM default, native optional).
- Runs taint rules per language for injection/path/SSRF/deserialization/XSS with scoped taint + sanitizer tracking.
-
External language adapters
- Runs optional tool adapters when installed (Bandit, gosec, Brakeman, Semgrep).
- Each adapter only runs if matching files exist and the tool is on PATH.
-
Infra/config patterns
- Scans Dockerfile, Terraform, and Kubernetes/Helm YAML for risky defaults.
-
Dependency scan
- Reads
package.json,package-lock.json, andrequirements.txt. - Matches against CVE cache or API and adds recommendations.
- Reads
-
Reporting
- Outputs text, JSON, or SARIF.
- Optional
--fail-on/--fail-on-highfor CI gating.
OpenSecurity can run optional external tools when they are installed and found on PATH.
bandit→ Pythongosec→ Gobrakeman→ Rubysemgrep→ Java, C#, PHP, Rust, Kotlin, Swift, C/C++
Adapters only run when matching files exist. Use --disable-adapters to skip or --adapters to whitelist.
Native AST/taint uses Tree‑sitter grammars. WASM grammars live in assets/grammars.
Build them locally:
npm run build-grammarsThis repo ships prebuilt WASM grammars for the 10 native languages. If they are missing, OpenSecurity will try native Tree‑sitter bindings (if installed) and otherwise skip native taint for that language with a warning.
| Language | AST/Taint (Tree‑sitter) | Rules |
|---|---|---|
| Python | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Deserialization, Template XSS, Weak Crypto, Hardcoded Secret |
| Go | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Template XSS, Weak Crypto, Hardcoded Secret |
| Java | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Deserialization, Template XSS, Weak Crypto, Hardcoded Secret |
| C# | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Deserialization, Template XSS, Weak Crypto, Hardcoded Secret |
| Ruby | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Deserialization, Template XSS, Weak Crypto, Hardcoded Secret |
| PHP | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Deserialization, Template XSS, Weak Crypto, Hardcoded Secret |
| Rust | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Template XSS, Weak Crypto, Hardcoded Secret |
| Kotlin | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Template XSS, Weak Crypto, Hardcoded Secret |
| Swift | ✅ | SQLi, Command Injection, Path Traversal, SSRF, Template XSS, Weak Crypto, Hardcoded Secret |
| C/C++ | ✅ | Command Injection, Path Traversal, Weak Crypto, Hardcoded Secret |
Rule coverage is heuristic and may miss context; validate findings in your environment.
Built-in infra checks include:
- Dockerfile:
USER root, privileged flags/capabilities. - Kubernetes/Helm YAML:
privileged,allowPrivilegeEscalation,readOnlyRootFilesystem:false,runAsNonRoot:false,runAsUser:0,seccompProfile: Unconfined,hostNetwork/hostPID/hostIPC,hostPath. - Terraform: public security group ingress, public ACLs, public S3 ACLs, disabled S3 public access block, public RDS instances.
- YAML: insecure TLS (
insecureSkipVerify,verify_ssl: false).
opensecurity scan [options]Common options:
--format <format>:text|json|sarif(default:text)--include <pattern...>/--exclude <pattern...>: override project filters--rules <path>: rules JSON override--cve-cache <path>: CVE cache JSON--cve-api-url <url>: CVE lookup API endpoint--simulate: include payload + impact for dependency findings--provider <provider>:openai|anthropic|google|mistral|xai|cohere--ai-all-text: allow AI scan on all text files (non-JS/TS) (default)--ai-js-only: limit AI scan to JS/TS only--path <path>: scan a specific file or directory--diff-only: scan only files changed in git--diff-base <ref>: git base ref for diff-only (default: HEAD)--ai-multi-agent: split AI scan into worker batches--ai-batch-size <n>: files per AI worker batch (default: 25)--ai-batch-depth <n>: path depth for AI batching (default: 2)--ai-cache: enable AI per-file cache (default)--no-ai-cache: disable AI per-file cache--ai-cache-path <path>: path to AI cache file--native-taint: enable native multi-language taint engine (default)--no-native-taint: disable native multi-language taint engine--native-langs <list>: comma-separated native languages (python,go,java,csharp,ruby,php,rust,kotlin,swift,c,cpp)--native-cache: enable native taint cache (default)--no-native-cache: disable native taint cache--native-cache-path <path>: path to native taint cache file--adapters <list>: comma-separated adapter ids (bandit,gosec,brakeman,semgrep)--disable-adapters: disable external static adapters--dependency-only: only run dependency scan--no-ai: disable AI scanning--dry-run: list matched files without scanning--fail-on <severity>: exit 1 if findings >= severity--fail-on-high: exit 1 if findings >= high--sarif-output <path>: write SARIF alongside primary output--concurrency <n>: parallel scan workers--max-chars <n>: max chars per chunk for AI scanning
Example commands:
opensecurity scan --no-ai
opensecurity scan --format sarif --sarif-output reports/opensecurity.sarif
opensecurity scan --provider anthropic --model claude-sonnet-4-20250514
opensecurity scan --dependency-only --simulate
opensecurity scan --ai-multi-agent --ai-batch-size 25 --ai-batch-depth 2
opensecurity scan --diff-only --diff-base main
opensecurity scan --path src/
opensecurity scan --adapters bandit,gosec
opensecurity scan --disable-adapters
opensecurity scan --native-langs python,go,javaopensecurity login --mode oauth
opensecurity login --mode api_key
opensecurity login --mode api_key --provider anthropicStores auth config in ~/.config/opensecurity/config.json.
opensecurity proxy --port 8787Runs a local OAuth proxy for the OAuth flow.
opensecurity telemetry on
opensecurity telemetry off- CLI flags
- Project config (
.opensecurity.json) - Global config (
~/.config/opensecurity/config.json) - Built-in defaults
Project config: .opensecurity.json
{
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["**/*.test.ts"],
"rulesPath": "rules.json",
"cveCachePath": "cve-cache.json",
"cveApiUrl": "https://example.com/osv",
"dataSensitivity": "medium",
"maxChars": 4000,
"concurrency": 2,
"aiCache": true,
"aiCachePath": ".opensecurity/ai-cache.json",
"nativeTaint": true,
"nativeTaintLanguages": ["python", "go", "java", "csharp", "ruby", "php", "rust", "kotlin", "swift", "c", "cpp"],
"nativeTaintCache": true,
"nativeTaintCachePath": ".opensecurity/native-taint-cache.json",
"adapters": ["bandit", "gosec", "brakeman", "semgrep"],
"noAdapters": false
}Global config: ~/.config/opensecurity/config.json
{
"provider": "openai",
"apiKey": "sk-...",
"baseUrl": "https://api.openai.com/v1/responses",
"model": "gpt-4o-mini",
"apiType": "responses",
"authMode": "api_key",
"authProfileId": "codex",
"oauthProvider": "proxy",
"providerApiKey": "..."
}Default rules are in src/engines/rules/defaultRules.ts.
Taint rule coverage by language: docs/coverage-matrix.md.
You can override with a JSON file (--rules or rulesPath).
Pattern-based detectors run alongside rules (hardcoded secrets, insecure crypto, unsafe deserialization).
Rule schema (simplified):
{
"id": "rule-id",
"name": "Human name",
"severity": "low|medium|high|critical",
"owasp": "A03:2021 Injection",
"sources": [{ "id": "src", "name": "getUserInput", "matcher": { "callee": "getUserInput" } }],
"sinks": [{ "id": "sink", "name": "eval", "matcher": { "callee": "eval" } }],
"sanitizers": [{ "id": "san", "name": "escape", "matcher": { "callee": "escape" } }]
}- Text: grouped by severity
- JSON: machine-readable, includes
schemaVersion - SARIF: for CI and code scanning tools
- Do not commit secrets.
- AI scanning sends code chunks to the configured API endpoint.
- Use
--no-aiif you want purely local scanning. - This tool provides best-effort findings and should be validated in your environment.
Supported providers for AI scanning:
- OpenAI (Responses or Chat Completions)
- Anthropic Messages API
- Google Gemini API
- Mistral Chat Completions API
- xAI Chat Completions API
- Cohere Chat API
API keys can be stored via opensecurity login --mode api_key --provider <provider> or set via environment:
OPENAI_API_KEYANTHROPIC_API_KEYGEMINI_API_KEYMISTRAL_API_KEYXAI_API_KEYCOHERE_API_KEY
When an API key is available, the model picker will try to fetch a live model list for the provider.
- Run
npm test,npm run lint, andnpm run buildbefore submitting changes. - Keep changes focused and add tests for new behavior.
- Do not add or log real secrets.
- For large changes, open an issue first to align on scope.
See CONTRIBUTING.md for full guidelines.
If you discover a vulnerability:
- Prefer opening a private Security Advisory on GitHub (if enabled), or
- Open a minimal public issue without sensitive details and request private follow‑up.
For questions or help, open a GitHub issue with clear reproduction steps.
npm install
npm run dev -- scan --dry-run
npm run build
npm link
opensecurity scan --dry-run
npm testMIT (see LICENSE).