Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 64 additions & 2 deletions initiatives/genai_red_team_handbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,71 @@ initiatives/genai_red_team_handbook
└── llm_local
```

## System Requirements

This project supports **Linux** and **macOS**. Windows users are encouraged to use WSL2 (Windows Subsystem for Linux).

### Required Tools

* **[Podman](https://podman.io/)**
* **[Ollama](https://ollama.com/)**
* **[Python 3.10+](https://www.python.org/)**
* **[uv](https://github.com/astral-sh/uv)**
* **[Make](https://www.gnu.org/software/make/)**

Required for Promptfoo:

* **[Node.js (v18+)](https://nodejs.org/)**
* **[npx](https://docs.npmjs.com/cli/v10/commands/npx)**

### Installation Instructions

#### macOS

1. **Install Dependencies**:
```bash
brew install podman ollama node make
```

2. **Initialize Podman Machine**:
```bash
podman machine init
podman machine start
```

#### Linux (Ubuntu/Debian)

1. **Install Dependencies**:
```bash
sudo apt-get update
sudo apt-get install -y podman nodejs npm make
```

2. **Install Ollama**:
```bash
curl -fsSL https://ollama.com/install.sh | sh
```

3. **Install uv**:
```bash
pip install uv
```

### Verification

Verify the installation by checking the versions of the installed tools:

```bash
podman version
ollama --version
node --version
make --version
uv --version
```

## Index of Sub-Projects

### Sandboxes
### `sandboxes/`

* **[Sandboxes Overview](sandboxes/README.md)**
* **Summary**: The central hub for all available sandboxes. It explains the purpose of these isolated environments and lists the available options.
Expand All @@ -31,7 +93,7 @@ initiatives/genai_red_team_handbook
* [Adding New Mock Services](sandboxes/llm_local/app/mocks/README.md): Guide for extending the sandbox with new API mocks.


### Exploitation
### `exploitation/`

* **[Red Team Example](exploitation/example/README.md)**
* **Summary**: Demonstrates a red team operation against a local LLM sandbox. It includes an adversarial attack script (`attack.py`) targeting the Gradio interface (port 7860). By targeting the application layer, this approach tests the entire system—including the configurable system prompt—providing a more realistic assessment of the sandbox's security posture compared to testing the raw LLM API in isolation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Python
__pycache__/
*.py[cod]
*$py.class
.venv/
.env
tmp

# Logs
logs/*.html
logs/*.log
logs/*.md
167 changes: 167 additions & 0 deletions initiatives/genai_red_team_handbook/exploitation/agent0/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
SANDBOX ?=
SANDBOX_DIR := ../../sandboxes/$(SANDBOX)
PROMPT_FILE ?=

.PHONY: help run stop all check-sandbox setup-env lock sync prompt format \
prepare-settings convert-logs ui

-include .env
export


# Default target
help: ## Display this help message
@echo "Usage: make <target> [SANDBOX=<name>] [PROMPT_FILE=<path>]"
@echo ""
@echo "Available targets:"
@echo " help Display this help message."
@echo " run Run the Red Team attack"
@echo " (starts sandbox and agent0)."
@echo " stop Stop and remove the sandbox and agent0"
@echo " containers."
@echo " all Clean, then run everything."
@echo " prompt Send a prompt to agent0"
@echo " (default: OWASP_Top10_LLM_App)."
@echo " Note: .md extension is optional."
@echo " format Format code with black, isort, and check"
@echo " with mypy."
@echo " convert-logs Convert HTML logs in logs/ to Markdown."
@echo " sync Synchronize uv dependencies."
@echo " lock Lock uv dependencies."
@echo " prepare-settings Prepare settings.json and .env files."
@echo " setup-env Run sync, lock, and prepare-settings."
@echo " check-sandbox Verify SANDBOX variable is set."
@echo " ui Open agent0 UI in browser after running."
@echo ""
@echo "Environment:"
@echo " - Sandbox Directory: $(SANDBOX_DIR)"
@echo ""
@echo "Example: make run SANDBOX=llm_local"

sync:
uv sync

lock:
uv lock

prepare-settings:
@echo "🔧 Preparing settings.json and .env..."
@mkdir -p $(CURDIR)/tmp
@if [ -z "$$GOOGLE_API_KEY" ]; then \
echo "⚠️ GOOGLE_API_KEY is not set. Please set it in .env or" \
"environment."; \
cp config/settings.json $(CURDIR)/tmp/settings.json; \
else \
sed 's/"api_keys": {}/"api_keys": {"google": \
"'$$GOOGLE_API_KEY'"}/' \
config/settings.json > $(CURDIR)/tmp/settings.json; \
fi
@echo "A0_PERSISTENT_RUNTIME_ID=automated_red_team" > $(CURDIR)/tmp/.env
@echo "AUTH_LOGIN=" >> $(CURDIR)/tmp/.env
@echo "AUTH_PASSWORD=" >> $(CURDIR)/tmp/.env
@echo "GOOGLE_API_KEY=$$GOOGLE_API_KEY" >> $(CURDIR)/tmp/.env

setup-env: sync lock prepare-settings

check-sandbox:
@if [ -z "$(SANDBOX)" ]; then \
echo "Error: SANDBOX is not set."; \
echo "Usage: make <target> SANDBOX=<name>"; \
echo "Example: make run SANDBOX=llm_local"; \
exit 1; \
fi

check-sandbox-and-prompt-file: check-sandbox
@if [ -z "$(PROMPT_FILE)" ]; then \
echo "Error: PROMPT_FILE is not set."; \
echo "Usage: make <target> PROMPT_FILE=<path>"; \
echo "Example: make prompt PROMPT_FILE=custom"; \
exit 1; \
fi

# Normalize PROMPT_FILE to include .md extension if missing
ifneq ($(PROMPT_FILE),)
ifeq ($(suffix $(PROMPT_FILE)),)
override PROMPT_FILE := $(PROMPT_FILE).md
endif
endif

convert-logs: ## Convert HTML logs to Markdown
@echo "🔧 Converting HTML logs to Markdown..."
@mkdir -p logs
@for f in logs/*.html; do \
base=$$(basename $$f .html); \
if [ ! -f logs/$$base.md ]; then \
echo "Converting $$f..."; \
pandoc -f html -t gfm -o logs/$$base.md $$f; \
perl -i -pe 's/\\n/\n/g' logs/$$base.md; \
sed -i '' -E '/^[[:space:]]*\\}$$/d' logs/$$base.md; \
fi; \
done

format:
uv run black .
uv run isort .
uv run mypy .

run: check-sandbox prepare-settings
@echo "🚀 Setting up Red Team environment..."
$(MAKE) -C $(SANDBOX_DIR) run-gradio-headless
@echo "⏳ Waiting for service to be ready..."
@sleep 15
@echo "✅ Environment ready!"
@echo "Starting agent0 container..."
@podman pull agent0ai/agent-zero:latest
# Remove attacker if it already exists to avoid name conflict
-podman rm -f attacker 2>/dev/null || true
# Mount settings.json to /a0/tmp/settings.json because agent0 hardcodes it
# in python/helpers/settings.py:
# SETTINGS_FILE = files.get_abs_path("tmp/settings.json")
@podman run -d \
--name attacker \
--net sec_test_net \
-p 50001:80 \
-v $(CURDIR)/tmp/settings.json:/a0/tmp/settings.json \
-v $(CURDIR)/tmp/.env:/a0/.env \
agent0ai/agent-zero:latest
@echo "✅ agent0 started on http://localhost:50001"

stop: check-sandbox
@echo "🧹 Tearing down Red Team environment..."
-podman rm -f attacker 2>/dev/null || true
-$(MAKE) -C $(SANDBOX_DIR) stop-gradio
$(MAKE) -C $(SANDBOX_DIR) down
@echo "✅ Environment cleaned up!"

ui: stop run
@sleep 10
@open http://localhost:50001

prompt: setup-env stop run
@echo "🤖 Sending prompt to agent0..."
uv run run_agent.py --prompt-file $(PROMPT_FILE)
@echo "📄 Exporting logs to logs/..."
@mkdir -p logs
@podman cp attacker:/a0/logs/. logs/
$(MAKE) convert-logs
@echo "📝 Prepending metadata to Markdown logs..."
for f in logs/*.md; do \
if ! grep -q "SANDBOX=" $$f; then \
temp_file=$$(mktemp); \
echo "# Configuration Log" > $$temp_file; \
echo "" >> $$temp_file; \
echo "\`\`\`json" >> $$temp_file; \
echo "SANDBOX=$(SANDBOX)" >> $$temp_file; \
echo "PROMPT_FILE=$(PROMPT_FILE)" >> $$temp_file; \
echo "SETTINGS:" >> $$temp_file; \
cat $(CURDIR)/tmp/settings.json | \
sed 's/"api_keys": {.*}/"api_keys": {"google": "********"}/' >> $$temp_file; \
echo "" >> $$temp_file; \
echo "\`\`\`" >> $$temp_file; \
echo "" >> $$temp_file; \
echo "---" >> $$temp_file; \
echo "# Outputs" >> $$temp_file; \
cat $$f >> $$temp_file; \
mv $$temp_file $$f; \
fi; \
done
Loading