FastAPI scanner
shadowaudit's FastAPI scanner uses regex-based decorator pattern matching to extract route definitions from .py files.
How it works
The scanner reads each .py file line-by-line and matches decorator patterns like @app.get('/path') and @router.post('/path'). No Python runtime is required — shadowaudit reads the source as text.
Detected patterns
Pattern 1 — Direct app decorators
from fastapi import FastAPI
app = FastAPI()
@app.get('/users')
async def get_users():
return []
@app.post('/users')
async def create_user():
return {}
Pattern 2 — APIRouter decorators
from fastapi import APIRouter
router = APIRouter()
@router.get('/products')
async def list_products():
pass
@router.delete('/products/{id}')
async def delete_product(id: int):
pass
Pattern 3 — Path parameters
FastAPI uses {param} syntax (same as OpenAPI) — stored as-is:
@app.get('/users/{user_id}/posts/{post_id}')
async def get_user_post(user_id: int, post_id: int):
pass
# → GET /users/{user_id}/posts/{post_id}
Example scan output
shadowaudit --dir ./src --spec openapi.json --framework fastapi
[INFO] Running FastAPI route scanner...
[✓] Found 7 FastAPI routes in ./src
[INFO] GET /health → main.py:13 [no auth]
[INFO] GET /api/users → main.py:21 [auth]
[INFO] POST /api/users → main.py:26 [auth]
[INFO] GET /api/debug/test-data → main.py:38 [no auth]
Auth detection
shadowaudit detects FastAPI auth by scanning the decorator line and up to 10 lines below (the function signature where Depends() appears):
@router.get('/admin/users')
async def get_admin_users(
current_user: User = Depends(get_current_user) # ← auth detected
):
pass
Also detects inline dependencies:
@router.get('/secure', dependencies=[Depends(verify_token)])
async def secure_endpoint():
pass
Hardcoded FastAPI auth patterns
Depends( Security( oauth2_scheme get_current_user
verify_token HTTPBearer HTTPBasic APIKeyHeader
APIKeyQuery require_auth login_required jwt_required
current_user
Known limitations
include_routerprefixes —app.include_router(router, prefix='/api/v1')prefixes are detected but not yet applied to routes (tracked in issue #1)@app.api_route()multi-method decorator — not yet supported (regex only matches single-method decorators)APIRouter(prefix='/api/v1')— constructor prefix not yet reconciled