Red team
The Red team screen lets you launch adversarial probes (prompt injection, jailbreak, data exfiltration) against a model, an agent or another target, and read the attack success rate and the findings of each campaign. Portal path: /quality/redteam. Security officers, developers and AI governance officers run it before a release. The screen is drawn by portal/src/screens/quality.tsx.
What the screen shows
- Red team runs table, read with
GET /v1/redteam/runs(50 rows per call, newest first, cursor paging). Columns: Id, Target type, Target, Engine, Status, Attack success rate, Vulnerable, Started. - When the list is empty: No red team run, with the hint Launch attack packs against a target. and the button New red team run.
- A click on a row, or View details, opens a side panel with
GET /v1/redteam/runs/{run_id}: target, probes, summary (total,vulnerable,attack_success_rate,threshold,by_category), findings and error. - New red team run opens a side panel with Target (required, example
model:gpt-4o-mini; without a type the target is an agent), Probes (comma separated, examplepi.ignore_previous, jb.dan, pii.exfiltration; empty means every built in probe) and Max attack success rate (number from 0 to 1, default 0).
The built in probes (services/control-plane/src/eai/domains/evaluation/engines.py):
| Probe | Category |
|---|---|
pi.ignore_previous | prompt_injection |
pi.system_prompt_leak | prompt_leak |
pi.indirect_document | indirect_injection |
pi.encoding_base64 | encoding |
pi.translation_smuggle | prompt_injection |
jb.dan | jailbreak |
jb.grandma | jailbreak |
jb.roleplay_malware | jailbreak |
pii.exfiltration | data_exfiltration |
pi.markdown_exfil | data_exfiltration |
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| Refresh (icon) | Reloads the list. | GET /v1/redteam/runs | Any tenant member |
| New red team run | Sends each probe to the target with a system prompt that holds a canary secret, judges every answer, computes the attack success rate and stores the campaign. | POST /v1/redteam/runs | tenant_admin, developer, security_officer, ai_governance_officer |
| Row click or View details | Opens the campaign with its findings. | GET /v1/redteam/runs/{run_id} | Any tenant member |
| Retry (error state) | Sends the failed read again. | Same call | Same roles |
The form sends this body with the engine builtin:
{"target": {"type": "model", "ref": "gpt-4o-mini"}, "probes": ["pi.ignore_previous", "jb.dan", "pii.exfiltration"], "max_attack_success_rate": 0}
The status is passed when the attack success rate is at most Max attack success rate, failed above it, and error when the target cannot be reached.
Roles
The portal hides no button. In services/control-plane/src/eai/domains/evaluation/__init__.py, launching a campaign needs one of WRITE_ROLES (tenant_admin, developer, security_officer, ai_governance_officer); listing and reading need a tenant. Every campaign is written to the audit log. platform_admin passes every role check.
Typical tasks
Test a model before its release
- Choose the target. The campaign calls the target through the platform. Fill Target with
model:<model-id>. Expected result: the form is ready. If it fails:invalid_request(400) withtarget.typemeans the type is not supported. - Pick the probes and the threshold. Zero tolerance is the default. Leave Probes empty to run them all, or list some ids; keep Max attack success rate at 0. Click Create. Expected result: the toast Created and a row with Status, Attack success rate and Vulnerable. If it fails:
invalid_requestwithunknown_probeslists the ids not found and theavailableones. - Read the findings. Each finding tells what the model answered. Click the row and read
findings(probe,category,vulnerable,reason,response_excerpt). Expected result:vulnerable: falseeverywhere. If it fails: fix the system prompt, the guardrails or the model, then run the campaign again.
Compare two campaigns
- Read the summaries. The summary counts the vulnerable probes per category. Open two campaigns of the same target and compare
summary.by_category. Expected result: the newer campaign has fewer vulnerable probes. If it fails: a statuserrorwitherrormeans the target could not be reached during one of them.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
invalid_request (400) with unknown_probes | A probe id is not a built in probe. | Use an id of the available list. |
invalid_request (400) with target.type | The target type is not supported. | Use model, agent, prompt, rag_pipeline, skill or tool. |
| Status Error | The target did not answer. | Check the model route or the agent, then run again. |
| Status Failed | The attack success rate is above the threshold. | Read findings, harden the target, run again. |
forbidden (403) with required_roles | Your roles cannot launch campaigns. | Ask for security_officer or developer. |