Target
The target is the model or agent under test. It is described the same way every model in a campaign is: a name, how to reach it, and how to sample from it.
The same shape describes attack roles, judges, guardrails and the goal classifier, so once you can write a target you can write all of them.
target
A model HackAgent talks to: its name, how to reach it, and how to sample from it.
The same shape describes the target, every attack helper (role), every judge, every guardrail and the goal classifier.
| Field | Type | Default | Description |
|---|---|---|---|
name | string (at least 1) | required | The model to use, as the provider names it, e.g. gpt-4o-mini or llama3. Also used to label the model in results. |
connection | ConnectionSpec | required | How to reach the model. |
generation | GenerationSpec | see GenerationSpec | Sampling settings for every request. |
options | map of string to any | empty | Settings specific to one kind of agent that are neither connection nor sampling, e.g. the binary path of a CLI agent, ADK's user_id, or a web target's CSS selectors. |
target.connection
How to reach a model: which client to use, where it lives, and how to authenticate.
| Field | Type | Default | Description |
|---|---|---|---|
provider | string (at least 1) | required | A label for who serves the model (openai, ollama, vllm, local…). Informational only: launch tooling reads it, but the request path uses type. |
type | agent type | required | Which client talks to the model. This is the field that matters: it decides whether HackAgent calls a chat API (OPENAI, OLLAMA, LITELLM…) or drives an agent directly (CLAUDE_CODE, GOOGLE_ADK, WEB…). |
endpoint | string | unset | Base URL of the model's API. Leave it unset for an OLLAMA model and HackAgent reads OLLAMA_HOST, falling back to http://localhost:11434 — so a campaign runs against whichever Ollama the machine has without being edited. Writing the URL here pins it, which is what you want for a server at a fixed address. Local agents such as CLAUDE_CODE need none: they are launched, not called over HTTP. |
api_key_env | string | unset | Name of the environment variable that holds the API key, e.g. OPENAI_API_KEY. The key itself never goes in the campaign file. |
headers | map of string to string | empty | Extra HTTP headers sent with every request. An API key belongs in api_key_env, not here: a campaign file is committed and shared. |
timeout | number (> 0) | 120.0 | Seconds to wait for one reply before giving up. |
target.generation
Sampling settings applied to every request the model receives. All optional: anything left unset uses the provider's own default.
| Field | Type | Default | Description |
|---|---|---|---|
max_tokens | integer (>= 1) | unset | Longest reply, in tokens. |
temperature | number (>= 0.0) | unset | Randomness of the reply. 0 is the most deterministic. |
top_p | number (>= 0.0, <= 1.0) | unset | Nucleus sampling: only consider the most likely tokens whose probabilities add up to this value. |
frequency_penalty | number | unset | Discourage repeating the same tokens. |
presence_penalty | number | unset | Encourage introducing new topics. |
seed | integer | unset | Fixed random seed, for repeatable replies where the provider supports it. |
stop | string or list of string | unset | Text (or list of texts) at which the model stops writing. |
reasoning_effort | string | unset | How hard a reasoning model should think (low, medium, high), for providers that support it. |
response_format | map of string to any | unset | Ask for a structured reply, e.g. {"type": "json_object"}. |
extra_body | map of string to any | empty | Any other provider-specific request fields, passed through unchanged. |
thinking | boolean | unset | Turn a model's thinking mode on or off. Judges default to off. |
Agent types
connection.type decides how HackAgent talks to the model. It is the field that matters; provider is only a label.
Chat APIs, reached over HTTP and driven through LiteLLM: LITELLM, OPENAI, OLLAMA, LANGCHAIN. These need an endpoint, and an api_key_env when the provider requires a key. OLLAMA is the exception: leave its endpoint unset and HackAgent reads OLLAMA_HOST, so the campaign follows whichever Ollama the machine runs.
Agents, driven directly:
| Type | What it is |
|---|---|
GOOGLE_ADK | Native backend for a deployed Google ADK agent server. |
CLAUDE_CODE | Native backend for a locally-installed Claude Code CLI. |
CODEX | Native backend for a locally-installed Codex CLI. |
HERMES | Native backend for a locally-installed Hermes Agent CLI. |
WEB | Native backend that red-teams a website's chatbot by driving the live page. |
MCP, A2A exist in the format but have no backend, so a campaign using one fails to resolve.
Examples
A model served by Ollama on this machine
target:
name: llama3.2
connection:
provider: ollama
type: OLLAMA
endpoint: http://localhost:11434
An OpenAI-compatible endpoint, reading the key from the environment
target:
name: gpt-4o-mini
connection:
provider: openai
type: OPENAI
endpoint: https://api.openai.com/v1
api_key_env: OPENAI_API_KEY
generation:
temperature: 0.0
max_tokens: 512
A coding agent running locally, with no endpoint at all
target:
name: claude-code
connection:
provider: local
type: CLAUDE_CODE
options:
binary: claude