RedTeaming Framework is a Python-based red teaming toolkit for evaluating chatbot and LLM targets through YAML campaigns.
It currently supports:
- PyRIT for dataset, crescendo, and red-teaming style attacks
- Garak for probe-based attacks
- HTTP targets configurable through campaign YAML files
- JSON reports plus a Streamlit dashboard for analysis
The framework lets you describe a campaign like this:
- define the target to attack
- define a list of attack YAML files
- run the campaign with
main.py - execute PyRIT and/or Garak attacks against the target
- normalize outputs into a common report format
- save reports to
reports/ - inspect the results in the dashboard
In practice, the flow is:
campaign YAML
→ target config
→ attack YAML files
→ PyRIT / Garak execution
→ normalized AttackResult JSON files
→ dashboard view
.
├── main.py # CLI entrypoint
├── src/ # source code
│ ├── settings.py # runtime settings loaded from .env
│ ├── core/ # campaign loading, orchestration, reporting
│ └── frameworks/ # PyRIT and Garak integrations
├── examples/ # example campaigns, attacks, templates
├── config/ # runtime config files (e.g. generated Garak config)
├── reports/ # generated JSON reports
├── tests/ # test suite
├── .env.example # environment variable template
└── README.md
You need:
- Python 3
- a virtual environment
- a target HTTP endpoint to test
- the Python packages used by the repo
- PyRIT if you want to run PyRIT campaigns
- Garak if you want to run Garak campaigns
- Streamlit if you want to use the dashboard
This repository currently does not expose a pinned dependency manifest in the root, so install the dependencies required by your environment manually.
At minimum, the codebase uses packages such as:
python-dotenvpydanticrequestsPyYAMLstreamlitpytestpyritgarak
python3 -m venv .venv
source .venv/bin/activatecp .env.example .envThen edit .env for your setup.
The main variables are:
- PyRIT attacker LLM
PYRIT_ATTACKER_ENDPOINTPYRIT_ATTACKER_MODELPYRIT_ATTACKER_API_KEY
- PyRIT scorer LLM
PYRIT_SCORER_ENDPOINTPYRIT_SCORER_MODELPYRIT_SCORER_API_KEY
- PyRIT runtime
PYRIT_DB_PATH
- Always required
DEFAULT_TARGET_URLJSON_REPORTS_DIR
- Garak
GARAK_REPORTS_DIRGARAK_CONFIG_PATH
See .env.example for comments and defaults.
Run an example campaign:
python main.py "examples/campaigns/R1-Prompt Leakage/prompt_leakeage.yaml"Useful variants:
python main.py "examples/campaigns/R1-Prompt Leakage/prompt_leakeage.yaml" --log-level DEBUG
python main.py "examples/campaigns/R1-Prompt Leakage/prompt_leakeage.yaml" --skip-checks
python main.py "examples/campaigns/R1-Prompt Leakage/prompt_leakeage.yaml" --no-dashboardBy default, after a campaign run:
- reports are written to
reports/ - the Streamlit dashboard is launched automatically unless
--no-dashboardis used
A campaign defines:
- metadata
- one target
- an ordered list of attacks
Use examples/templates/campaign.yaml as the reference template.
campaign:
name: "My campaign"
description: "What this campaign is testing"
target:
name: "CustomerBot"
model: "gpt-4.1-nano"
architecture_type: "System Prompt + Context Injected"
chat_url: "http://localhost:8000/api/chat"
reset_memory_url: "http://localhost:8000/api/reset"
input_field: "prompt"
output_field: "response"
attacks:
- examples/attacks/some_attack.yaml
- examples/attacks/another_attack.yamlname: human-readable target namemodel: model name shown in logs and dashboardarchitecture_type: target architecture category shown in logs and dashboardchat_url: endpoint that receives the input messagereset_memory_url: optional endpoint used to reset target memory/contextinput_field: JSON field used to send the prompt to the targetoutput_field: JSON field read from the target response
Each item in attacks: is a path to an attack YAML file.
Paths are expected relative to the project root.
- executes a list of prompts
- treats prompts as independent objectives
- currently supports reset between prompts when configured in the runner/target flow
- multi-turn attack
- keeps conversational context across turns
- should not be reset between turns
- multi-turn objective-driven adversarial interaction
- uses attacker and scorer LLMs
- probe-based scanning
- uses the configured REST generator against the target HTTP API
The framework stores normalized JSON results in reports/.
Those reports are used by the dashboard and include metadata such as:
- framework
- attack name
- campaign name
- target URL
- target model
- target architecture type
- timestamp
Depending on the framework, a result contains either:
promptsfor Garak-style probe resultsconversationfor PyRIT conversation-style results
The dashboard is implemented in:
src/core/results/report_viewer.py
It provides three main views:
- Overview
- Campaigns
- Attacks
The dashboard shows campaign-level information such as:
- campaign name
- breach rate
- target model
- target architecture type
Run the test suite with:
pytestOr run a subset, for example:
pytest tests/frameworks/test_pyrit_runner.py
pytest tests/application/test_campaign_loader.py- targets are currently modeled as HTTP chat endpoints
- the framework expects text input/output fields in JSON
- campaign attack paths are root-relative
- the dashboard reads normalized JSON reports, not live campaign YAML files
- PyRIT and Garak have different execution models, but both are normalized into the same reporting layer
- add new example campaigns under
examples/campaigns/ - add new attacks under
examples/attacks/ - add framework logic under
src/frameworks/ - add orchestration or reporting logic under
src/core/ - add regression tests under
tests/
If you are new to the repo, start with:
README.mdmain.pyexamples/templates/campaign.yamlsrc/core/application/campaign_loader.pysrc/frameworks/pyrit/pyrit_runner.pysrc/frameworks/garak/garak_runner.py
That gives a good end-to-end view of how campaigns are loaded, executed, normalized, and reported.