Skip to main content

muzzle-optimizer

A superred port of MUZZLE (arXiv:2602.09222, "Adaptive Agentic Red-Teaming of Web Agents Against Indirect Prompt Injection Attacks"), an adaptive indirect-prompt-injection (IPI) attacker for tool-using agents.

Given an agentic target and an adversarial goal, MuzzleOptimizer:

  1. observes one benign run and summarizes the victim's trajectory into a playbook;
  2. ranks the in-scope content-injection surfaces (vessels) by salience;
  3. probes a vessel by planting a placeholder and checking it surfaces in the victim's context;
  4. crafts a context-aware payload with an offline PAIR loop (a simulated victim conditioned on the real system prompt and the localized context);
  5. attacks with one real run, then refines from feedback: a missed delivery moves to the next vessel, an ineffective payload is re-refined by PAIR.

Success is decided by the SecurityClaim (RunEndEvent.evaluation.success), never by the optimizer. See ASSUMPTIONS.md for the faithfulness ledger and every deliberate deviation from the upstream github.com/gsiros/muzzle (SHA ed611c0).

Install

pip install -e ./optimizers/muzzle

Depends only on superred and PyYAML. The Chao et al. PAIR core is vendored under muzzle_optimizer/pair/ (no cross-module dependency).

Usage

from muzzle_optimizer import MuzzleOptimizer
from superred.core.controller import Controller, TargetFactory

controller = Controller(
    optimizer_factory=lambda: MuzzleOptimizer(),   # zero-arg; a fresh instance per task
    target_factory=TargetFactory(create=make_agent_target, concurrency=1),
    security_claim=ipi_claim,
    scope=root_scope,
    llm_config=attacker_cfg,     # the one fixed attacker model MUZZLE's roles share
    max_runs_per_task=12,        # see "Run budget" below
)
result = await controller.run()

The optimizer adapts entirely from initialize(...); it takes no required constructor arguments. Useful keyword knobs include max_attempts, the PAIR caps (pair_n_streams, pair_n_iterations), target_controllable_name (pin a vessel for ablations), and response_observable_names.

How it maps to the framework

MUZZLE component superred
Explorer (Docker/Zoo/vLLM-proxy/red-team browser agent) the controller's run loop + the trajectory + a direct ControllableInjection
BENIGN / PROBE / ACTUAL victim runs successive target.run() calls in the multi-run loop
vessel (web UI element) an in-scope content Controllable (PostCall: tool:<name> / read__* / opi_tool_observation), with PreCall fallback
curl assertion oracle RunEndEvent.evaluation.success (the SecurityClaim)
Summarizer / Grafter / Prompter / Judge (gpt-4o agents) helper classes over the single self.llm, each with its byte-identical prompt
PAIR (offline, bare victim LLM) PairBridge: offline PAIR with self.llm as the surrogate victim

The optimizer runs a three-phase state machine over the multi-run loop: OBSERVE (passthrough recon -> playbook -> ranked vessels) -> PROBE (placeholder delivery check per vessel; a miss advances the vessel and is not scored) -> ATTACK (inject the PAIR payload; success ends the task, a UI-attributed failure tries the next vessel, an instruction-attributed failure re-refines).

Scope behavior

  • Content vessels in scope: the intended IPI setting; rank, probe, attack.
  • PreCall-only: degrade to a user_prompt (preferred) or system_prompt fallback vessel (less indirect, deprioritized).
  • No injectable surface: one OBSERVE passthrough, then done (the passthrough baseline). Never crashes.
  • include_feedback=False: steers by the trajectory presence/PROBE checks only and never self-certifies success.

Run budget

OBSERVE is a pure recon run, so a single phase cannot attack. Allow at least ~4-5 runs per goal (max_runs_per_task) so OBSERVE + PROBE + ACTUAL can complete; the offline PAIR loop consumes only the optimizer's LLM cost budget, not target runs. BudgetExhaustedError stops the task cleanly.

Tests

pip install -e "./optimizers/muzzle[test]"
pytest optimizers/muzzle/tests -q
mypy --strict optimizers/muzzle/src
ruff check optimizers/muzzle

smoke/ holds env-gated live end-to-end checks against real agentic targets (agentdojo, inspect_agent); they need an LLM proxy (LITELLM_API_KEY / LITELLM_API_BASE).

Credits / upstream

This module ports the MUZZLE red-teaming method to superred and vendors the PAIR attacker core. Our integration code is MIT (see LICENSE); upstream components keep their original licenses (see NOTICE and LICENSES/).

  • MUZZLE — Syros et al., "MUZZLE: Adaptive Agentic Red-Teaming of Web Agents Against Indirect Prompt Injection Attacks", arXiv:2602.09222 (2026). Source: https://github.com/gsiros/muzzle (Apache-2.0). The five agent prompt YAMLs, the four injection templates, the judge payload-presence heuristic, and the OBSERVE/PROBE/ATTACK control logic derive from this repo. Deviations from upstream are logged in ASSUMPTIONS.md.
  • PAIR — Chao et al., "Jailbreaking Black Box Large Language Models in Twenty Queries" (2023). Source: https://github.com/patrickrchao/JailbreakingLLMs (MIT, Copyright (c) 2023 PAIR Team). Vendored under muzzle_optimizer/pair/.

Please cite both papers when reporting results produced with this module.

Metadata

Release files for superred-optimizer-muzzle 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for superred-optimizer-muzzle 0.1.0
File Size Uploaded Provenance
superred_optimizer_muzzle-0.1.0.tar.gz 82.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for superred-optimizer-muzzle 0.1.0
File Interpreter ABI Platform
superred_optimizer_muzzle-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 149.4 kB

Release files / superred_optimizer_muzzle-0.1.0.tar.gz

Download URL superred_optimizer_muzzle-0.1.0.tar.gz
Size 82.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2452ddfd97d9a82c0db8198e9c715daaca9b1e7a7af375edb3da61acf881b904
BLAKE2b-256 checksum
How to use checksums
525aa3a49e60bc620b5b4902fee8821e239c03c2aed1cf13c4c5c382c689a177
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Release files / superred_optimizer_muzzle-0.1.0-py3-none-any.whl

Download URL superred_optimizer_muzzle-0.1.0-py3-none-any.whl
Size 67.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
75c3e411449bb31f20ef5e77117cd6932f61bcc12aec0c931313654faf6b052c
BLAKE2b-256 checksum
How to use checksums
f23b1963f179081d6e49d7027c3db1b65aded93d586a74d8346faba2429b3e0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Security for superred-optimizer-muzzle 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for superred_optimizer_muzzle-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page