PyRIT CLI - Command-line interface for running security scenarios.
This module provides the main entry point for the pyrit_scan command.
Functions¶
main¶
main(args: Optional[list[str]] = None) → intStart the PyRIT scanner CLI.
Returns:
int— Exit code (0 for success, 1 for error).
merge_config_scenario_args¶
merge_config_scenario_args(config_scenario: Optional[ScenarioConfig], effective_scenario_name: str, cli_args: dict[str, Any]) → dict[str, Any]Merge config-file scenario args with CLI scenario args (CLI wins per-key).
When config_scenario.name does not match effective_scenario_name, the
config args are skipped with a warning so users are not silently surprised.
Mutable values are deep-copied so they don’t leak across runs.
| Parameter | Type | Description |
|---|---|---|
config_scenario | Optional[ScenarioConfig] | The scenario: block from the layered config, or None when not configured. |
effective_scenario_name | str | The scenario about to run (CLI wins). |
cli_args | dict[str, Any] | Scenario args supplied on the CLI. |
Returns:
dict[str, Any]— dict[str, Any]: The merged scenario-args dict to pass toset_params_from_args.
parse_args¶
parse_args(args: Optional[list[str]] = None) → NamespaceParse command-line arguments using a two-pass flow.
Pass 1 identifies the scenario name with parse_known_args so unknown
scenario flags don’t fail. Pass 2 parses for real, with the resolved
scenario’s declared params added as namespaced flags.
The scenario name may come from the CLI positional or, as a fallback, from
the scenario.name block in --config-file (or the default config
file). This mirrors the runtime behavior in main() so config-only
scenario names can still expose their declared CLI flags.
The CLI positional is only trusted when it resolves to a known scenario.
Pass 1 doesn’t yet know about scenario-declared flags, so parse_known_args
can greedily consume an unknown flag’s value (e.g. the "7" in
--max-turns 7) as the positional. When that happens the positional won’t
resolve, and we fall back to the config peek.
| Parameter | Type | Description |
|---|---|---|
args | Optional[list[str]] | Argument list (sys.argv[1:] when None). Defaults to None. |
Returns:
Namespace— Parsed command-line arguments.
Parameter¶
Describes a parameter that a PyRIT component (initializer or scenario) accepts.
Scenario¶
Bases: ABC
Groups and executes multiple AtomicAttack instances sequentially.
A Scenario represents a comprehensive testing campaign composed of multiple atomic attack tests (AtomicAttacks). It executes each AtomicAttack in sequence and aggregates the results into a ScenarioResult.
Constructor Parameters:
| Parameter | Type | Description |
|---|---|---|
name | str | Descriptive name for the scenario. Defaults to ''. |
version | int | Version number of the scenario. |
strategy_class | Type[ScenarioStrategy] | The strategy enum class for this scenario. |
objective_scorer | Scorer | The objective scorer used to evaluate attack results. |
include_default_baseline | bool | Whether to include a baseline atomic attack that sends all objectives without modifications. Most scenarios should have some kind of baseline so users can understand the impact of strategies, but subclasses can optionally write their own custom baselines. Defaults to True. Defaults to True. |
scenario_result_id | Optional[Union[uuid.UUID, str]] | Optional ID of an existing scenario result to resume. Can be either a UUID object or a string representation of a UUID. If provided and found in memory, the scenario will resume from prior progress. All other parameters must still match the stored scenario configuration. Defaults to None. |
Methods:
default_dataset_config¶
default_dataset_config() → DatasetConfigurationReturn the default dataset configuration for this scenario.
This abstract method must be implemented by all scenario subclasses to return a DatasetConfiguration specifying the default datasets to use when no dataset_config is provided by the user.
Returns:
DatasetConfiguration— The default dataset configuration.
get_default_strategy¶
get_default_strategy() → ScenarioStrategyGet the default strategy used when no strategies are specified.
This abstract method must be implemented by all scenario subclasses to return the default aggregate strategy (like EASY, ALL) used when scenario_strategies parameter is None.
Returns:
ScenarioStrategy— The default aggregate strategy (e.g., FoundryStrategy.EASY, EncodingStrategy.ALL).
get_strategy_class¶
get_strategy_class() → type[ScenarioStrategy]Get the strategy enum class for this scenario.
This abstract method must be implemented by all scenario subclasses to return the ScenarioStrategy enum class that defines the available attack strategies for the scenario.
Returns:
type[ScenarioStrategy]— Type[ScenarioStrategy]: The strategy enum class (e.g., FoundryStrategy, EncodingStrategy).
initialize_async¶
initialize_async(objective_target: PromptTarget = REQUIRED_VALUE, scenario_strategies: Optional[Sequence[ScenarioStrategy]] = None, dataset_config: Optional[DatasetConfiguration] = None, max_concurrency: int = 10, max_retries: int = 0, memory_labels: Optional[dict[str, str]] = None) → NoneInitialize the scenario by populating self._atomic_attacks and creating the ScenarioResult.
This method allows scenarios to be initialized with atomic attacks after construction, which is useful when atomic attacks require async operations to be built.
If a scenario_result_id was provided in init, this method will check if it exists in memory and validate that the stored scenario matches the current configuration. If it matches, the scenario will resume from prior progress. If it doesn’t match or doesn’t exist, a new scenario result will be created.
| Parameter | Type | Description |
|---|---|---|
objective_target | PromptTarget | The target system to attack. Defaults to REQUIRED_VALUE. |
scenario_strategies | Optional[Sequence[ScenarioStrategy]] | The strategies to execute. Can be a list of ScenarioStrategy enum members. If None, uses the default aggregate from the scenario’s configuration. Defaults to None. |
dataset_config | Optional[DatasetConfiguration] | Configuration for the dataset source. Use this to specify dataset names or maximum dataset size from the CLI. If not provided, scenarios use their default_dataset_config(). Defaults to None. |
max_concurrency | int | Maximum number of concurrent attack executions. Defaults to 1. Defaults to 10. |
max_retries | int | Maximum number of automatic retries if the scenario raises an exception. Set to 0 (default) for no automatic retries. If set to a positive number, the scenario will automatically retry up to this many times after an exception. For example, max_retries=3 allows up to 4 total attempts (1 initial + 3 retries). Defaults to 0. |
memory_labels | Optional[Dict[str, str]] | Additional labels to apply to all attack runs in the scenario. These help track and categorize the scenario. Defaults to None. |
Raises:
ValueError— If no objective_target is provided.
run_async¶
run_async() → ScenarioResultExecute all atomic attacks in the scenario sequentially.
Each AtomicAttack is executed in order, and all results are aggregated into a ScenarioResult containing the scenario metadata and all attack results. This method supports resumption - if the scenario raises an exception partway through, calling run_async again will skip already-completed objectives.
If max_retries is set, the scenario will automatically retry after an exception up to the specified number of times. Each retry will resume from where it left off, skipping completed objectives.
Returns:
ScenarioResult— Contains scenario identifier and aggregated list of all attack results from all atomic attacks.
Raises:
ValueError— If the scenario has no atomic attacks configured. If your scenario requires initialization, call await scenario.initialize() first.ValueError— If the scenario raises an exception after exhausting all retry attempts.RuntimeError— If the scenario fails for any other reason while executing.
set_params_from_args¶
set_params_from_args(args: dict[str, Any]) → NonePopulate self.params from merged CLI / config arguments.
Coerces each value to its declared param_type, validates, and
materializes declared defaults for params not in args. Every
declared parameter is guaranteed a key in self.params after this
call; params without a declared default land as None.
| Parameter | Type | Description |
|---|---|---|
args | dict[str, Any] | Map of parameter name to raw value. Keys with None values are treated as absent (YAML null). Argparse callers should use argparse.SUPPRESS. |
Raises:
ValueError— Invalid declaration, unknown parameter, coercion failure, or value not inchoices.
supported_parameters¶
supported_parameters() → list[Parameter]Override to declare custom parameters this scenario accepts.
Declared parameters flow from CLI/config through set_params_from_args
into self.params before initialize_async() runs. Implemented as
a classmethod so --list-scenarios can introspect without instantiating.
Note: PyRITInitializer.supported_parameters is an instance @property;
this asymmetry is intentional pending a future alignment.
Returns:
list[Parameter]— list[Parameter]: Declared parameters (default: empty list).