Doramagic Project Pack · Human Manual

bandit

Bandit is a tool designed to find common security issues in Python code.

Overview, Installation & CLI Usage

Related topics: Core Engine Architecture & Data Flow, Configuration, Output Formatters & Extensibility

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Key Argument Groups

Continue reading this section for the full explanation and source context.

Section Execution Flow

Continue reading this section for the full explanation and source context.

Section Output Formats and Color

Continue reading this section for the full explanation and source context.

Related topics: Core Engine Architecture & Data Flow, Configuration, Output Formatters & Extensibility

Overview, Installation & CLI Usage

Purpose and Scope

Bandit is a tool designed to find common security issues in Python code. It is a static analysis linter that walks the Python abstract syntax tree (AST) of each file and runs plugin-based checks against the nodes. Source: bandit/cli/main.py:1-7 and bandit/__init__.py. The project ships several command-line entry points that cover the typical security-review workflow: the primary bandit scanner, a bandit-baseline diff tool for comparing commits, and bandit-config-generator for producing configuration templates.

The primary entry point is exposed as both a script and a module — running python -m bandit invokes bandit/__main__.py, which then delegates to the CLI handler in bandit/cli/main.py. Source: bandit/__main__.py.

Installation

Bandit is distributed as a standard Python package and can be installed with pip. The CLI scripts become available on PATH after installation. The baseline subcommand requires an additional Git dependency (provided by the baseline extra), which is what allows bandit-baseline to manipulate a working tree. Source: bandit/cli/baseline.py:64-73.

Common extras include:

ExtraProvidesUsed by
baselineGitPython integrationbandit-baseline subcommand
testTest runner dependenciesRepository CI
tomlTOML config supportpyproject.toml configuration

Support for pyproject.toml as a configuration format has been a long-standing community request (issue #550), and a toml extra is shipped to support it.

The Main `bandit` CLI

The primary command-line interface is defined in bandit/cli/main.py. The argument parser wires targets, test selection, severity/confidence filtering, output format, exclusion patterns, and baseline comparison into a single argparse.ArgumentParser. Source: bandit/cli/main.py:202-399.

Key Argument Groups

ArgumentPurpose
targetsPositional list of files or directories to scan.
-r, --recursiveDiscover files in subdirectories.
-a, --aggregateAggregate output by file (default) or vuln.
-t, --testsComma-separated list of test IDs to run.
-s, --skipComma-separated list of test IDs to skip.
-ll, -lllFilter by severity / confidence via repeated flags.
-f, --formatOutput format (txt, json, html, csv, custom, screen, ...).
--msg-templateCustom formatter template (only with --format custom).
-x, --excludeComma-separated glob patterns to exclude.
-b, --baselineJSON baseline to compare against.
--iniPath to a .bandit config file.
--exit-zeroAlways exit with code 0, even with findings.

Source: bandit/cli/main.py:213-399.

Execution Flow

The CLI drives a three-step pipeline managed by bandit.core.manager.BanditManager:

flowchart LR
    A[Parse args + .bandit] --> B[discover_files]
    B --> C[run_tests via plugins]
    C --> D[output_results]
    D --> E{Results above\nseverity/conf?}
    E -- yes & !exit-zero --> F[exit 1]
    E -- no --> G[exit 0]

Source: bandit/cli/main.py:470-509.

Logger output is initialized before the parser runs so that errors during argument resolution are visible. Source: bandit/cli/main.py:186-200.

Output Formats and Color

The default output format is chosen automatically: screen when stdout is a TTY and NO_COLOR/TERM=dumb are not set, otherwise txt. Source: bandit/cli/main.py:340-355.

The custom formatter accepts a Python str.format()-style template. Available tags include {abspath}, {relpath}, {line}, {col}, {test_id}, {severity}, {msg}, {confidence}, and {range}. Source: bandit/cli/main.py:160-180.

The `.bandit` Project File

Bandit automatically discovers a .bandit file in any scanned directory tree and merges its values into the CLI defaults. The discovery is performed by walking targets and collecting files matching .bandit. Source: bandit/cli/main.py:74-95.

A typical file looks like:

[bandit]
exclude: ./tests,./.tox
tests: B101,B102
skips: B404

When multiple .bandit files are found, Bandit emits a warning. The supported keys map to long-form CLI options (level, confidence, format, msg-template, output, verbose, debug, quiet, ignore-nosec, exclude, skips, tests, ini-options, etc.). Source: bandit/cli/main.py:130-190.

Community note: Excluding paths via .bandit has had regressions over time — issue #488 reports that bandit -x ./tests/ was not respected after 1.6.0, and issue #657 reports that the exclude: value in the .bandit file was not being applied in 1.6.3. Always double-check with --verbose to confirm the resolved exclude list.

The tool also supports pyproject.toml and setup.cfg as configuration sources (issues #212 and #550), letting projects consolidate dev-tool settings into a single file.

Baseline Comparison

bandit-baseline compares the current working tree against a parent commit in a Git repository. It performs the following sequence:

  1. Validates that the working directory is a clean Git repo (with GitPython). Source: bandit/cli/baseline.py:14-19, bandit/cli/baseline.py:174-185.
  2. Resolves the current and parent commit hashes. Source: bandit/cli/baseline.py:100-118.
  3. Runs bandit against the parent commit, writing JSON results to a temporary file. Source: bandit/cli/baseline.py:120-149.
  4. Resets to the current commit, runs bandit with -b <tmpfile>, and reports only new findings. Source: bandit/cli/baseline.py:120-149.
  5. Restores the original HEAD on exit (via the baseline_setup context manager). Source: bandit/cli/baseline.py:152-158.

The tool enforces that the working tree is clean, that git is on PATH, that no pre-existing bandit_baseline_result.* file is present, and that the user did not pass -o (which would clash with the managed report filename). Source: bandit/cli/baseline.py:163-190.

Valid output formats for the final report are txt, html, and json; terminal is the default and prints directly to stdout. Source: bandit/cli/baseline.py:27-141.

Configuration Generation

bandit-config-generator emits a templated YAML profile listing every loaded plugin, its default settings, and optional include/skip lists. Use --show-defaults to print defaults to stdout without writing a file. Source: bandit/cli/config_generator.py:60-95.

The generator inspects each plugin's module for a gen_config function and, if present, dumps its output into the YAML template. Source: bandit/cli/config_generator.py:97-114. Plugin IDs supplied via --tests/--skips are validated against the extension manager and rejected if unknown. Source: bandit/cli/config_generator.py:67-87.

Common Failure Modes and Gotfalls

  • Stale .bandit files: When multiple .bandit files are present, only one is honored and a warning is logged. Move the file to the project root.
  • -o with baseline: bandit-baseline refuses to run if -o is in argv, because it manages its own report filename.
  • Dirty tree with baseline: The baseline tool requires a clean working directory so it can git reset safely.
  • Per-file skips: The community has repeatedly requested a one-liner to skip a test only in files matching a glob (issue #346). At present, the supported approaches are -s B101 (global skip) and per-line # nosec comments combined with --ignore-nosec control. Source: bandit/cli/main.py:381-390.

See Also

  • Plugin authoring and AST node checks
  • bandit.core.manager reference
  • Severity and confidence ranking
  • CI/CD integration recipes

###TASK_COMPLETED###

Source: https://github.com/PyCQA/bandit / Human Manual

Core Engine Architecture & Data Flow

Related topics: Overview, Installation & CLI Usage, Security Plugins & Built-in Checks, Configuration, Output Formatters & Extensibility

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Logging and Extension Bootstrap

Continue reading this section for the full explanation and source context.

Section Argument Parsing and Config Merging

Continue reading this section for the full explanation and source context.

Section File Discovery

Continue reading this section for the full explanation and source context.

Related topics: Overview, Installation & CLI Usage, Security Plugins & Built-in Checks, Configuration, Output Formatters & Extensibility

Core Engine Architecture & Data Flow

Overview and Purpose

Bandit is a static analysis tool that scans Python source code for common security issues. The "core engine" is the orchestration layer that ties together user input (CLI flags, INI config files, baseline files), the plugin/test ecosystem (extensions, blacklists, formatters), the file discovery walk, and the test execution pipeline that ultimately produces a security report.

While bandit.core houses the test runner primitives (BanditManager, TestSet, testers, AST visitor), the CLI entry points in bandit.cli are what wire those primitives to user input and drive the end-to-end data flow. This page focuses on that wiring, since it is what determines how arguments, configuration, files, and findings actually flow through the system. Source: bandit/cli/main.py.

The engine has three CLI sub-commands that share core machinery:

Sub-commandModuleRole
banditbandit.cli.mainPrimary analyzer: discover → test → report
bandit-baselinebandit.cli.baselineCompare current commit findings to parent commit
bandit-conf-generatorbandit.cli.config_generatorEmit a YAML config skeleton with plugin defaults

High-Level Data Flow

The CLI follows a linear pipeline: bootstrap logging and extensions, merge configuration sources, walk the filesystem, run AST-based tests against each file, then format and write the results. The pipeline is shown below.

flowchart TD
    A[main: parse CLI args] --> B[_get_options_from_ini: load .bandit]
    B --> C[_log_option_source: merge CLI > INI > defaults]
    C --> D[_init_extensions: load plugins/formatters]
    D --> E[BanditManager: discover_files]
    E --> F[BanditManager: run_tests]
    F --> G[BanditManager: output_results]
    G --> H[Exit code: 0 clean / 1 findings / 2 error]

Each stage is small and explicit, which is why most user-visible regressions (e.g. the exclude-path bugs reported in issues #488 and #657) trace back to a specific stage in this flow rather than to the test plugins themselves.

Stage-by-Stage Breakdown

Logging and Extension Bootstrap

main() raises the log level to DEBUG if --debug is present, otherwise defaults to INFO, then calls _init_logger() which clears any existing handlers, attaches a StreamHandler to stderr, and enables logging.captureWarnings(True) so Python warnings surface in the report. Source: bandit/cli/main.py.

_init_extensions() returns an entrypoints-backed extension manager. The CLI uses it twice: first to enumerate plugins and blacklists for the --help epilog (so users can see "the following tests were discovered and loaded"), and again to discover formatters that advertise _accepts_baseline for the --baseline flow. Source: bandit/cli/main.py.

Argument Parsing and Config Merging

Bandit accepts an INI file via --ini <path> or by walking targets for a .bandit file. _get_options_from_ini() performs this discovery and returns a dict of values; if more than one .bandit is found during the walk it logs a warning and picks one deterministically. Source: bandit/cli/main.py.

The _log_option_source() helper is the merge point. For each option it prefers (in order) the CLI value, then the INI value, then the argparse default, and emits an INFO log line naming the winning source. This is the mechanism that drove issues #212 ("Add config via setup.cfg") and #550 ("Support for pyproject.toml as config file format") — community members want additional config sources plugged into this same merge function. Source: bandit/cli/main.py.

Recognized INI keys include level, confidence, format, msg-template, output, verbose, debug, quiet, ignore-nosec, tests, targets, recursive, aggregate, number, profile, and exclude. The exclude key is particularly load-bearing for issues #488 ("Bandit 1.6.0 no longer respects excluded directories") and #657 ("Bandit 1.6.3 does not respect excluded paths from .bandit file"); both were caused by mis-merges between CLI -x/--exclude and INI exclude. Source: bandit/cli/main.py.

File Discovery

After argument merging, the CLI instantiates the BanditManager and calls b_mgr.discover_files(args.targets, args.recursive, args.excluded_paths). The manager walks the targets, applies glob-style exclusion against args.excluded_paths (which is the union of CLI -x, INI exclude, and constants.EXCLUDE), and populates b_mgr.b_ts.tests. If no tests remain after filtering, main() logs "No tests would be run, please check the profile." and exits with code 2. Source: bandit/cli/main.py.

Test Execution

b_mgr.run_tests() is where the AST is parsed and every registered tester walks it. Severities and confidences are translated from numeric levels (1=all, 2=low, 3=medium, 4=high) into the constants.RANKING index used downstream. Issues like #346 ("One-liner in bandit config to skip B101 assert_used in files matching a filter") point at this stage — the current engine only supports global include/skip via -t/-s and per-path exclusion via -x, with no per-file test skipping hook. Source: bandit/cli/main.py.

Results Output and Exit Codes

b_mgr.output_results(context_lines, sev_level, conf_level, output_file, output_format, msg_template) renders findings through the chosen formatter. If output_format == "custom" is set, args.msg_template may use any of {abspath}, {relpath}, {line}, {col}, {test_id}, {severity}, {msg}, {confidence}, {range} with Python str.format style specifiers; otherwise the template flag is rejected by parser.error(). Source: bandit/cli/main.py.

The exit code is derived from results_count(sev_filter, conf_filter) > 0 combined with --exit-zero: findings present and not suppressed ⇒ exit 1, otherwise 0. A configuration or discovery failure exits 2. Source: bandit/cli/main.py.

Baseline Sub-Command

bandit-baseline reuses the same engine twice against different git revisions. baseline_setup() creates a temp directory and is guaranteed (via @contextlib.contextmanager) to remove it and reset repo.head to current_commit after the run. The two steps are:

  1. Reset repo.head to the parent commit, run bandit -f json -o <tmpfile> <args>.
  2. Reset repo.head back to the current commit, run bandit -b <tmpfile> -f <format> <args>.

Pre-flight checks abort with exit 2 if GitPython is missing, the cwd is not a repo, the working tree is dirty, the report file already exists, the temp file already exists, or -o was passed (which would clash with baseline-managed output). The final exit code is whatever the second Bandit invocation returned. Source: bandit/cli/baseline.py.

Config Generator Sub-Command

bandit-conf-generator (bandit.cli.config_generator) walks every loaded plugin that exposes _takes_config and calls its module-level gen_config() to collect default settings, then serializes the result with yaml.safe_dump. The --show-defaults flag prints to stdout; -o writes a fully annotated profile template containing an # Available tests: comment list, optional tests/skips selections, and per-plugin settings blocks. Source: bandit/cli/config_generator.py.

See Also

  • Configuration File Support & Merge Semantics
  • Plugin and Blacklist Architecture
  • Baseline Reporting Workflow
  • Issue #488 and #657 for the historical exclude-path regressions discussed above.

Source: https://github.com/PyCQA/bandit / Human Manual

Security Plugins & Built-in Checks

Related topics: Core Engine Architecture & Data Flow, Configuration, Output Formatters & Extensibility

Section Related Pages

Continue reading this section for the full explanation and source context.

Section CLI flags

Continue reading this section for the full explanation and source context.

Section Project config files

Continue reading this section for the full explanation and source context.

Section Per-plugin configuration

Continue reading this section for the full explanation and source context.

Related topics: Core Engine Architecture & Data Flow, Configuration, Output Formatters & Extensibility

Security Plugins & Built-in Checks

Bandit ships as a library of pluggable AST-walking security checks. The bandit/plugins/ package contains every check that runs by default, and the project's CLI, configuration, and baseline tools are all written to consume that plugin set through a single extension manager. This page documents how the plugin system is organized, what categories of checks are provided, and how to select or configure them in practice.

Plugin Architecture

Every Bandit check is a Python module that exposes one or more decorated test functions. These are discovered at import time by the core extension loader, exposed as extension_loader.MANAGER.plugins, and surfaced to the CLI as a flat list of id + name pairs.

flowchart LR
    A[bandit/plugins/*.py] -->|decorated test fns| B(extension_loader.MANAGER)
    B --> C[PluginRegistry<br/>plugins + blacklist]
    C --> D[bandit/cli/main.py<br/>--tests / --skip / -t / -s]
    C --> E[bandit/cli/config_generator.py<br/>gen_config]
    C --> F[BanditManager<br/>profile include/exclude]
    F --> G[AST visitor results]

The registry distinguishes two kinds of entries. extension_mgr.plugins_by_id holds the AST checks that run against the source, while extension_mgr.blacklist holds blacklist-style lookups such as hardcoded-password string detection. The CLI builds its Available tests help text by walking both collections, which is why a single bandit --help output lists plugin IDs and blacklist IDs together. Source: bandit/cli/main.py

Test IDs are short alphanumeric tokens such as B101, B406, or B613. They are stable across releases and are what users put in .bandit config files, setup.cfg, or pyproject.toml to opt in or out of a check. Source: bandit/cli/config_generator.py

Built-in Check Categories

The built-in checks are organized by vulnerability family. Each family lives in its own module under bandit/plugins/ and registers one or more test functions with a common prefix.

Plugin moduleTest ID prefixWhat it flags
asserts.pyB101Use of assert in production code paths
exec.pyB102Calls to exec, eval, or compile of dynamic code
general_hardcoded_password.py(blacklist)String literals that look like passwords or secrets
injection_shell.pyB6xxos.system, subprocess with shell=True, unquoted format-string shell calls
injection_sql.pyB6xxString-built SQL passed to execute / executemany

These are the families exercised by the Bandit test suite and referenced in the release notes. Source: bandit/plugins/asserts.py, bandit/plugins/exec.py, bandit/plugins/general_hardcoded_password.py, bandit/plugins/injection_shell.py, bandit/plugins/injection_sql.py

A practical example: B101 assert_used reports any assert statement, which is a common source of false positives in test_*.py files. Community discussion in issue #346 has long requested a per-file-pattern override so that B101 can stay enabled globally but be muted inside pytest test trees. Source: bandit/plugins/asserts.py

Selecting and Configuring Checks

Bandit provides three layered ways to control which plugins run.

CLI flags

The -t/--tests and -s/--skip flags accept comma-separated test IDs. The CLI parses them, merges them into the active profile, and calls extension_mgr.validate_profile(profile) to ensure no test appears in both lists. Source: bandit/cli/main.py

Project config files

A .bandit file, a setup.cfg [bandit] section, or a pyproject.toml [tool.bandit] table can all carry the same options. The config layer is read by _get_options_from_ini, which walks target directories looking for a .bandit file unless --ini is passed explicitly. Source: bandit/cli/main.py

Note that two long-standing community pain points live here: issue #488 and #657 report that excluded paths from .bandit have been silently ignored in 1.6.x releases, and issue #212 plus #550 request first-class support for setup.cfg and pyproject.toml. Users on recent 1.9.x releases should re-verify the exclude and skips keys after upgrading.

Per-plugin configuration

Plugins that need configuration expose a _takes_config decorator and a gen_config(function._takes_config) helper. The config generator CLI walks extension_loader.MANAGER.plugins, imports each plugin's module, and dumps a YAML template containing every available knob with its default. This is the supported way to tune things like the SQL injection wordlist or the shell-injection skipping sets. Source: bandit/cli/config_generator.py

A minimal config file that turns on only the shell and SQL injection families looks like:

tests:
  - B602
  - B603
  - B604
  - B605
  - B606
  - B607
skips:
  - B101

Severity, Confidence, and `# nosec`

Once a plugin reports a finding, the result carries two integer ranks (severity and confidence). The CLI converts them with the constants.RANKING table and args.severity / args.confidence counters, so -i/-ii/-iii and -l/-ll/-lll filter findings before they reach the report. Source: bandit/cli/main.py

Individual lines can be opted out with a trailing # nosec comment. The --ignore-nosec flag disables that escape hatch globally, which is useful for CI gates that want every check to be answered explicitly. Source: bandit/cli/main.py

Community Notes

  • The most frequently discussed "annoyance" is B101 in pytest trees (#346). The supported workaround today is the global -s B101 flag or a per-file # nosec marker; per-glob disabling inside .bandit is still an open request.
  • Configuration portability is an active theme. Issues #212 and #550 track setup.cfg and pyproject.toml support respectively. On 1.9.x the .bandit file remains the most reliably parsed format, but setup.cfg sections are also accepted via the same INI parser path.
  • The bandit-baseline subcommand is implemented in bandit/cli/baseline.py. It shells out to bandit twice (parent commit, current commit), then diffs JSON output. Baseline files must therefore be JSON, and the -o flag is rejected by the baseline tool to avoid clobbering its own report file.
  • The 1.9.4 release notes mention a crash fix for B613 when reading from stdin. If a check is fed python -c content or bandit -, the AST visitor must be able to handle a missing filename; recent plugin updates cover this case.

See Also

Source: https://github.com/PyCQA/bandit / Human Manual

Configuration, Output Formatters & Extensibility

Related topics: Overview, Installation & CLI Usage, Core Engine Architecture & Data Flow, Security Plugins & Built-in Checks

Section Related Pages

Continue reading this section for the full explanation and source context.

Section 1.1 Configuration Sources and Precedence

Continue reading this section for the full explanation and source context.

Section 1.2 The .bandit INI Format

Continue reading this section for the full explanation and source context.

Section 1.3 YAML Profiles and the Config Generator

Continue reading this section for the full explanation and source context.

Related topics: Overview, Installation & CLI Usage, Core Engine Architecture & Data Flow, Security Plugins & Built-in Checks

Configuration, Output Formatters & Extensibility

Bandit is a static analyzer that scans Python code for common security issues. To make it usable across projects of varying scale, Bandit exposes three orthogonal extension surfaces: a layered configuration system (CLI flags, .bandit INI files, and YAML profiles), a formatter plugin system that controls how findings are presented, and a generic extension manager that discovers and registers test plugins, blacklists, and formatters at runtime. This page documents how those surfaces are implemented and how they interact.

1. Configuration System

1.1 Configuration Sources and Precedence

Bandit accepts configuration from three distinct sources. The order in which they are merged is implemented in bandit/cli/main.py:

  1. Built-in defaults registered through bandit/core/constants.py (for example EXCLUDE, log_format_string).
  2. Project-level .bandit INI file, discovered by walking the target tree for files literally named .bandit via fnmatch.filter(filenames, ".bandit") in bandit/cli/main.py. The file may also be supplied explicitly with --ini.
  3. Command-line arguments parsed by argparse.

The helper _log_option_source in bandit/cli/main.py implements the precedence rule: an explicit CLI value always wins; otherwise an INI value is preferred over the default. The function also emits an INFO log line such as Using command line arg for excluded paths so users can audit which source actually took effect.

1.2 The `.bandit` INI Format

The INI parser reads a [bandit] section. Recognized keys include exclude, tests, skips, targets, recursive, aggregate, number, profile, level, confidence, format, msg-template, output, verbose, debug, quiet, ignore-nosec, and baseline (mapped via repeated _log_option_source calls in bandit/cli/main.py). The community has repeatedly asked for richer filtering inside .bandit, for example in issue #346 requesting the ability to skip B101 only for files matching a glob — that capability is not implemented today; exclusions are path-glob based only.

1.3 YAML Profiles and the Config Generator

When a richer, per-plugin configuration is needed (for example tuning the blacklist word lists for B324), Bandit reads a YAML profile through bandit/core/config.py and the BanditConfig class. Profiles are selected with -p PROFILE and merged on top of the INI layer. _get_profile in bandit/cli/main.py looks up the named profile under config.get_option("profiles"), falling back to the global tests/skips options when no profile name is supplied.

The CLI ships a sibling tool, bandit/cli/config_generator.py, that introspects every loaded plugin via extension_loader.MANAGER.plugins, calls gen_config(plugin._takes_config) for plugins that expose configuration metadata, and dumps a fully-commented YAML template using yaml.safe_dump. This lets users bootstrap a profile without hand-writing keys.

2. Output Formatters

2.1 Built-in Formats

Formatters are loaded by bandit/core/extension_loader.py through the extension_mgr.formatter_names registry, which is consumed by the --format argparse choice list in bandit/cli/main.py. The default is detected dynamically: screen is used when sys.stdout.isatty() and NO_COLOR is unset, otherwise txt is chosen, ensuring CI logs remain plain.

The custom format is intentionally minimal — it only enables formatting when --format custom is set together with --msg-template, otherwise argparse.error is raised. The epilog in bandit/cli/main.py lists the available template tags: {abspath}, {relpath}, {line}, {col}, {test_id}, {severity}, {msg}, {confidence}, and {range}. Python str.format mini-language is fully supported, so width and alignment specifiers work.

2.2 Output Targets and Aggregation

Two flags shape output delivery:

FlagPurposeSource
-o / --outputRedirects the rendered report to a file (defaults to sys.stdout)bandit/cli/main.py
-a / --aggregateAggregates findings by file (default) or by vuln (issue identity)bandit/cli/main.py
-n / --numberLimits the code-context window printed around each findingbandit/cli/main.py

2.3 Baseline Comparison

For diff-driven reviews, the bandit-cli-baseline entry point runs Bandit against both HEAD~1 and HEAD, writes the parent run to a JSON file (-f json -o bandit_baseline.json_), then invokes the current run with -b baseline.json_ so only newly introduced issues are reported. The tool uses git.Repo(os.getcwd()), requires a clean working tree, and refuses to run if the JSON baseline file already exists.

3. Extensibility Architecture

Bandit's extensibility rests on a single extension_loader namespace created by bandit.core.extension_loader (source). It exposes three registries:

flowchart LR
    A[Python entry points<br/>bandit.plugins / bandit.formatters / bandit.blacklists] --> B[extension_loader.MANAGER]
    B --> C[Test Plugins<br/>extension_mgr.plugins_by_id]
    B --> D[Formatters<br/>extension_mgr.formatter_names]
    B --> E[Blacklists<br/>extension_mgr.blacklist / blacklist_by_id]
    C --> F[BanditManager]
    D --> F
    E --> F
    F --> G[Issue results]

The BanditManager in bandit/core/manager.py consumes these registries to populate its _plugins, _blacklist_by_test_id, and formatter maps. Each plugin may declare _takes_config, which is what the config generator iterates over. Plugins may also expose gen_config to advertise their defaults (see the loop in bandit/cli/config_generator.py).

External packages add capabilities simply by registering Python entry points under the bandit.plugins, bandit.formatters, and bandit.blacklists groups; no Bandit source changes are required. The _log_info function in bandit/cli/main.py prints which tests are included via the profile versus the CLI, which is the canonical way to confirm a third-party plugin was discovered.

4. Known Limitations and Community Workarounds

Several pain points surface repeatedly in the issue tracker and are worth documenting so contributors do not rediscover them:

  • -x exclude precedence: Issue #488 reported that the exclude key in .bandit was silently overridden by the default EXCLUDE constant when -x was also passed. The current _log_option_source logic in bandit/cli/main.py fixes this by clearly preferring the CLI when present, but the same logic was briefly regressed (issue #657), so users upgrading from 1.6.x should re-test exclusions.
  • Alternate config files: Issues #212 and #550 ask for setup.cfg and pyproject.toml support. Neither is currently implemented; the only project-level config file Bandit auto-discovers is .bandit.
  • Per-file skip rules: Issue #346 requests a "one-liner" to skip B101 only for tests/ files. As of release 1.9.4 this requires either splitting the scan into multiple invocations or using per-line # nosec comments respected via the ignore_nosec flag.

See Also

  • Core Architecture & Manager
  • Built-in Plugins Reference
  • Output Formatters Reference

Source: https://github.com/PyCQA/bandit / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Security or permission risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Capability evidence risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Maintenance risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Security or permission risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 8 structured pitfall item(s), including 1 high/blocking item(s). Top priority: Security or permission risk - Security or permission risk requires verification.

1. Security or permission risk: Security or permission risk requires verification

  • Severity: high
  • Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PyCQA/bandit/issues/1397

2. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | https://github.com/PyCQA/bandit

3. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/PyCQA/bandit

4. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | https://github.com/PyCQA/bandit

5. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: risks.scoring_risks | https://github.com/PyCQA/bandit

6. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PyCQA/bandit/issues/1432

7. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: issue_or_pr_quality=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/PyCQA/bandit

8. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: release_recency=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/PyCQA/bandit

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using bandit with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence