Skip to main content

Adversarial red-team scanner for AI agents — versioned attack corpus, cage action-ground-truth, signed DrillReport

Project description

blastcontain-drill

Adversarial red-team scanner for AI agents. Drill runs a versioned attack corpus against an agent inside a cage and scores the result on two planes — what the model said (content) and what the agent did (action). It produces a signed, MITRE-ATLAS-tagged DrillReport in the same Audit-Packet format as blastcontain-verify.

The cage trilogy: Verify proves the cage is built right · Drill attacks the agent inside it · Guard adds the runtime locks.

pip install blastcontain-drill
blastcontain-drill --agent-id my-agent --cage inprocess \
  --target-base-url http://localhost:1234/v1 --target-model qwen/qwen3.6-27b \
  --report drill.md --output drill.json

What makes Drill different

Existing tools score the model's output (jailbroken text, PII in a response). Drill, running the agent in a cage, also scores the action: did the canary actually leave? did a forbidden tool fire? did the agent attempt an egress the cage blocked? Content scoring says "the model said something bad." Drill says "the agent did something bad."

Plane Asks How
Content did the model say something bad? LLM-as-judge + a guardrail classifier (Qwen3Guard or IBM Granite Guardian)
Action did the agent do something bad? cage ground truth — canary exfil · forbidden-tool fire · egress attempt · tool-call log

A scenario returns HELD or BYPASS with a detection latency and the control that blocked it. An action-plane bypass is CRITICAL and blocks prod promotion.

The attack corpus — three layers, versioned

Layer Source Catches
Replay built-in seeds · JailbreakBench · system-card checks · multi-turn vectors · AI-Infra-Guard curated sets known attacks — a regression suite
Operators arXiv techniques as transforms (PyRIT/DeepTeam encoders, framing, obfuscation, homoglyph…) known methods on fresh seeds
Generative an abliterated attacker model in a PAIR/TAP loop novel jailbreaks

Every run is pinned to a corpus version (e.g. v2026.06.1) and recorded in the DrillReport, so reports are reproducible and regression-comparable.

Replay sources (opt-in, mix per run):

  • Built-in seed corpus — always on, version-pinned (BUILTIN_CORPUS_VERSION), ATLAS-tagged.
  • --jbb — JailbreakBench (100 harmful + 100 benign over-refusal probes, dataset revision pinned).
  • --systemcard — cyber-misuse / dual-use, identity & leaked-info honesty, ART indirect-injection probes.
  • --multiturn — long-context reference tracking, decomposition/recompose, and real multi-turn crescendo (a conversation carried across turns, not a single prompt).
  • --enable-aig — AI-Infra-Guard as a live attack-source plugin (if the service is up).

Operators (--operators) applies model-free string transforms (base64, ROT13, Caesar, Atbash, Morse, binary, url-encode, reverse, leetspeak, many-shot, persona, payload-split, prefix-injection, multilingual, char-space, zero-width, homoglyph) to every seed, expanding each into fresh variants while preserving its category/goal. No model required — fast and reproducible.

Generative (--generative) runs an abliterated/no-refusal attacker model against the caged target in a PAIR/TAP loop (--attacker-model). Discovered jailbreaks are written to a separate, sensitive corpus (--generative-corpus), never into the signed report (which carries only an excerpt).

The cage

The cage is an interface with two backends:

  • inprocess — host-side cage that drives a real model (any OpenAI-compatible endpoint, e.g. LM Studio) through an agent loop with a tool allowlist, an egress allowlist, a planted canary, and a tool-call log. Used for live runs and fast tests.
  • podman — a real container with deny-all egress (--network none), proving containment ground truth. Runs a non-LLM stub agent in CI.

Both produce the same observations, so the action probes (canary / egress / forbidden-tool) score identically against either.

Taxonomy

Every finding is tagged with MITRE ATLAS (primary; verified against atlas.mitre.org), plus the MIT AI Risk domain and OWASP Agentic T#. The agent techniques AML.T0086 (Exfiltration via AI Agent Tool Invocation) and AML.T0110 (AI Agent Tool Poisoning) cover the action plane. The maps live in blastcontain-core.

CLI flags (most common)

--agent-id              Target agent identifier (required)
--env                   dev | uat | staging | prod
--cage                  inprocess | podman   (default: inprocess)
--target-base-url       OpenAI-compatible endpoint for the in-cage agent
--target-model          model id to drive as the agent (e.g. qwen/qwen3.6-27b)
--judge-base-url        endpoint for the LLM judge (defaults to --target-base-url)
--judge-model           model id for the content-plane judge
--judge-kind            llm | geval               (default: llm; geval needs [judge] extra)
--guard-model           guardrail classifier id (auto-selects Qwen3Guard / Granite Guardian / WildGuard)
--agent-url             attack an already-running agent over HTTP (black-box mode)
--corpus                corpus version to pin (default: built-in latest)
--scenarios             comma-separated categories (default: all)
--charter               local charter.yaml — its permitted_tools define "forbidden"

# Corpus source toggles (see "The attack corpus" above)
--jbb                   include JailbreakBench (100 harmful + 100 benign)
--systemcard            include system-card checks (cyber-misuse, honesty, ART indirect)
--multiturn             include multi-turn vectors (long-context, decomposition, crescendo)
--enable-aig            include AI-Infra-Guard as a live attack source
--operators             expand every seed with model-free technique transforms
--generative            run the generative attacker loop
--attacker-model        attacker model id (abliterated/heretic; required with --generative)
--generative-corpus     write discovered jailbreaks (SENSITIVE; separate from --output)

--output PATH           write the signed DrillReport JSON
--report PATH           write the Markdown report

Verifying a DrillReport

import json
from blastcontain_core.signing import verify_packet

packet = json.load(open("drill.json"))
assert verify_packet(packet)

Ed25519 packets carry their public key inline. Set BLASTCONTAIN_SIGNING_KEY_PATH to an Ed25519 PEM for production attestation; otherwise an advisory HMAC is used.

Container

# from the blastcontain-oss/ root (dev build — installs core from local source)
podman build -t blastcontain-drill:0.1.0 -f drill/Containerfile .

# black-box: attack a running agent
podman run --rm -v "$PWD/reports:/reports:rw" blastcontain-drill:0.1.0 \
  --agent-id my-agent --agent-url http://agent:8080 \
  --report /reports/drill.md --output /reports/drill.json

Drill drives a model, so — unlike Verify — it is not run with --network none. To point the inprocess cage at a model server on the host, see the Containerfile header.

Safety

Drill emits live adversarial payloads. Run the corpus and any attacker model in the cage, treat generated jailbreaks as secrets, and check dataset licenses before redistribution. See SECURITY.md.

License

Apache 2.0. See NOTICE.

Contributing

See CONTRIBUTING.md. All contributions require a DCO sign-off (git commit -s).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blastcontain_drill-0.2.0.tar.gz (144.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

blastcontain_drill-0.2.0-py3-none-any.whl (120.8 kB view details)

Uploaded Python 3

File details

Details for the file blastcontain_drill-0.2.0.tar.gz.

File metadata

  • Download URL: blastcontain_drill-0.2.0.tar.gz
  • Upload date:
  • Size: 144.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for blastcontain_drill-0.2.0.tar.gz
Algorithm Hash digest
SHA256 47ceb43a53f14e5a0d2bda3eb7fea6f1bddf215fab4d42ef3712108318b5a39a
MD5 3c579e879751191a5abadfa7a11046fe
BLAKE2b-256 8d353b27af247d4af4b39ee7ef30a53e361f4a3bc2014308c2f340798fc7c936

See more details on using hashes here.

Provenance

The following attestation bundles were made for blastcontain_drill-0.2.0.tar.gz:

Publisher: release.yml on gdeudney/blastcontain-oss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blastcontain_drill-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for blastcontain_drill-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 df83cfdd9f3b95a0b6b7b708755f3e86b927da0e4840e5c40471a9ae6a7ac1b3
MD5 49fc4fdf76cc9a4553521f84ef223970
BLAKE2b-256 9a793c2795323f2034276050014fc6cfe20d8b53b50b692b052f012c1a3d8730

See more details on using hashes here.

Provenance

The following attestation bundles were made for blastcontain_drill-0.2.0-py3-none-any.whl:

Publisher: release.yml on gdeudney/blastcontain-oss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page