bandit -r: Static Security Scan for Python
bandit -r <path> recursively scans Python files for security issues (B-prefixed checks) and exits 1 when issues are reported.
Bandit is the standard SAST tool for Python. It walks the AST looking for patterns like assert in production, weak hashes, or shell=True, each tagged with a B-code.
What it does
bandit parses each Python file into an AST and runs its plugin checks (B101 assert, B602 subprocess shell=True, etc.). Exit 1 means issues were found at the configured severity/confidence, exit 0 means clean. -r is required to recurse into a directory.
Common usage
bandit -r ./src
# only report medium+ severity and high confidence
bandit -r ./src -ll -ii
# skip a noisy test directory
bandit -r . -x ./tests,./buildOptions
| Flag | What it does |
|---|---|
| -r <path> | Recurse into the directory |
| -l / -ll / -lll | Min severity: low / medium / high to report |
| -i / -ii / -iii | Min confidence: low / medium / high |
| -x, --exclude <paths> | Comma-separated paths to skip |
| -s, --skip <tests> | Skip specific checks, e.g. B101,B601 |
| -f, --format <fmt> | screen, json, sarif, html, csv |
| -c, --configfile <f> | Config file (.bandit / pyproject) of options |
In CI
bandit exits 1 on findings, so it fails the job automatically; tune the noise with -ll -ii (medium severity, medium confidence) rather than turning the gate off. Exclude test code with -x ./tests since asserts there are expected. Inline # nosec suppresses a single line when justified.
Common errors in CI
"No tests were specified" or scanning nothing means -r was omitted on a directory. "syntax error while parsing AST from file" means bandit hit Python it cannot parse (often a different Python version or a non-Python file); exclude it. A green build despite obvious issues usually means the severity/confidence thresholds (-ll -ii) filtered them out.