Frequently Asked Questions
Does shadowaudit require an OpenAPI spec?
Yes for delta comparison (finding undocumented routes), but you can:
- Run without a spec to just list all routes in your codebase
- Generate a spec from your code using
--generate-spec(v0.4.0+)
# Just list routes — no spec comparison
shadowaudit --dir ./src --framework express
# Generate a spec from your code (v0.4.0+)
shadowaudit --dir ./src --framework express --generate-spec > openapi.json
What is --diff mode?
--diff mode (v0.6.0+) shows only NEW findings since the last scan — perfect for PR workflows where you don't want to see the same 50 pre-existing findings on every PR.
shadowaudit --dir ./src --spec ./openapi.json --diff
- First run: full scan, cache saved to
.shadowaudit-cache.json - Subsequent runs: only new findings shown, resolved findings shown as ✓
- Exit code based on new findings only (pre-existing don't fail CI)
- Use
actions/cachein GitHub Actions to persist the cache between runs
Does it work on monorepos?
Yes. Point --dir at any subdirectory:
shadowaudit --dir ./packages/api/src --spec ./packages/api/openapi.json
For multi-service repos, run shadowaudit multiple times — once per service:
shadowaudit --dir ./packages/api/src --spec ./packages/api/openapi.json --format sarif > api.sarif
shadowaudit --dir ./packages/auth/src --spec ./packages/auth/openapi.json --format sarif > auth.sarif
What's the difference between CRITICAL and HIGH?
| Severity | Condition | CI behavior |
|---|---|---|
| CRITICAL | Undocumented route + no auth middleware detected | Pipeline fails by default |
| HIGH | Undocumented route + auth middleware present | Pipeline passes (review recommended) |
| INFO | Informational finding | Pipeline passes |
Use --fail-on to control which severities fail the pipeline:
# Default — fail on CRITICAL only
shadowaudit --fail-on critical
# Stricter — fail on CRITICAL or HIGH
shadowaudit --fail-on high
# Strictest — fail on any finding
shadowaudit --fail-on info
Is it free?
Fully free and MIT licensed. No license keys, no rate limits, no telemetry, no phone-home. The source code is on GitHub.
If shadowaudit helps you, consider sponsoring the project to support development.
How is this different from Snyk or 42Crunch?
| Tool | What it does | What it misses |
|---|---|---|
| Snyk | Finds dependency vulnerabilities (CVEs in npm packages) | Routes that exist in code but aren't in your spec |
| 42Crunch | Validates documented APIs against spec (rate limits, params) | Routes that aren't documented at all |
| shadowaudit | Finds routes in code that are NOT in your spec | Dependency vulnerabilities |
They're complementary — Snyk finds vulnerable dependencies, 42Crunch validates your spec, and shadowaudit finds the routes those tools never see.
Does it send my code anywhere?
No. shadowaudit runs entirely locally — it reads your source files and OpenAPI spec on disk. No code is uploaded, no telemetry is sent, no phone-home.
The only network call is when you use the GitHub Action's PR comment bot, which posts the findings summary to the GitHub API (using github.token).
What languages and frameworks are supported?
| Framework | Language | Status |
|---|---|---|
| Express.js | JavaScript / TypeScript | ✅ Full support |
| FastAPI | Python | ✅ Full support |
| Django | Python | ✅ Full support |
| Flask | Python | 🚧 Coming soon |
| Koa | JavaScript | 🚧 Planned |
| NestJS | TypeScript | 🚧 Planned |
Request a framework here.
Can I use it in pre-commit hooks?
Yes. Add to your .pre-commit-config.yaml:
- repo: local
hooks:
- id: shadowaudit
name: shadowaudit
entry: shadowaudit --dir ./src --spec openapi.json --fail-on critical
language: system
files: \.(js|ts|py)$
pass_filenames: false