Skip to main content

Little Canary

Little Canary — prompt injection sensing through a sacrificial model

Screen untrusted prompts for signs of injection before your agent acts.

Little Canary runs untrusted text through a powerless "canary" model first and watches what it does. A host integration can use the verdict to block the input or restrict downstream tool authority, depending on that host's capabilities.

PyPI Python 3.9+ License: Apache-2.0

Quick start · Integrations · How it works · Research · Website


The problem

A prompt injection looks like ordinary data — a web page, an email, a tool result — until your agent follows the instructions hidden inside it. Pattern-matching filters can miss attacks that do not match known patterns. By the time you notice, the agent has already acted.

The idea

Coal miners sent a canary in first. Little Canary does the same thing for agents:

  1. Send the untrusted text to a canary model that has no tools, no credentials, and nothing to lose.
  2. Inspect the canary's response for signs the input changed its behavior.
  3. Return a verdict (PASS, FLAG, BLOCK) for the host to enforce within its available interception points.

Structural checks run alongside to catch known attack shapes. The canary can reveal attacks that no pattern check has catalogued yet.

Little Canary screening output: clean input passes, injected input is blocked

Little Canary is developed by Hermes Labs.

Quick start (2 minutes)

Requires Python 3.9+ and a local Ollama install.

pip install little-canary
ollama pull qwen2.5:1.5b
little-canary demo --live --backend ollama --model qwen2.5:1.5b --endpoint http://127.0.0.1:11434

The demo sends one clean input and one injected input through your local canary and prints both responses, the signals it found, and the verdict for each. You'll see whether the canary followed the attack and whether Little Canary caught it.

Results depend on the canary model you run.

Screen your own input

Start the local screening service:

little-canary serve --mode block --canary-model qwen2.5:1.5b --ollama-url http://127.0.0.1:11434

Send it anything untrusted:

curl -sS http://127.0.0.1:18421/check \
  -H 'Content-Type: application/json' \
  -d '{"text":"untrusted text"}'

The service binds to loopback only and exposes GET /health. Your application reads the verdict and decides what to do before forwarding the input.

Python apps can skip HTTP and call SecurityPipeline.check() directly — see the example integrations.

The default remains qwen2.5:1.5b. Select an installed model with serve --canary-model, demo --model, or Python's SecurityPipeline(canary_model=...); the Hermes Agent plugin reads LITTLE_CANARY_MODEL. Locally exercised alternatives are qwen3.5:2b-q4_K_M, LiquidAI/lfm2.5-1.2b-instruct:q4_k_m, and gemma3:1b. Pull weights with ollama pull <tag> and check each model's license. These are selectable models, not performance guarantees; see the evaluation guidance.

Reading a verdict

Verdict Meaning What to do
PASS Inspection ran and found no covered compromise signal. Proceed.
FLAG Suspicious behavior observed. Log it, restrict tools, or ask a human.
BLOCK Configured policy rejects the input. Apply the host's documented blocking behavior.
DEGRADED / UNSCREENED Behavioral inspection didn't complete or didn't run. Treat as unscreened, not as clean.

Routing and coverage are separate. A fail-open setup can let a turn continue while reporting degraded coverage. Don't mistake that for a behavioral pass. Failed canary coverage can include a coverage_reason in the layer result, such as output_limit or timeout; this diagnostic does not change the verdict.

Known false-block limitation: quoted attack phrases in security reports can trigger a structural BLOCK; harmless canary acknowledgements can also trigger behavioral rules. In block mode, legitimate work can be blocked. Little Canary has no built-in pause-and-approve UI; hosts can use advisory routing and implement review where their interception point allows it. See the host capability matrix.

Put it in front of your agent

Run the local service above, then wire in the host you use. Not every host lets a plugin refuse a prompt; the host capability matrix records exactly what each one can intercept and block.

Host Integration Can it block the turn?
Claude Code Plugin screens UserPromptSubmit Yes
Gemini CLI Extension screens BeforeAgent Yes — denies the run before the loop starts
OpenAI Agents SDK Input guardrail maps verdicts to the SDK tripwire Yes — before the first agent starts
OpenClaw Native plugin, install below Yes — current prompt only, not history or tool results
Hermes Agent Native plugin screens the user turn No — a block removes downstream tool authority instead
OpenClaw install

From a Little Canary checkout:

openclaw plugins install ./plugins/openclaw --force
openclaw plugins enable little-canary-openclaw
openclaw config set plugins.entries.little-canary-openclaw.hooks.allowConversationAccess true

Review the conversation-access permission before enabling it.

What Little Canary is and isn't

  • It's a sensing layer. It sits alongside tool policy, sandboxing, and human review — it doesn't replace them.
  • The canary is powerless at the application layer, not isolated by an OS sandbox.
  • A PASS means no covered signal was found in this inspection. It doesn't mean the input is safe under every circumstance.
  • Detection rates depend on your model, your policy, and the attack. Benchmarks and methodology show how we measure it and where it misses.

We'd rather you know the edges than find them in production.

Research

The behavioral canarying technical note explains the powerless-model probe and why a routing decision must stay separate from whether inspection actually ran.

Contributing

Found an injection that got through? Open an issue with a safe reproducer and the observed result. For fixes or integrations, run the offline tests and Ruff, then open a pull request. The contributor guide has setup and submission details.

Benchmarks · Host capability matrix · Security policy · Releases

License

Apache-2.0. The source version lives in pyproject.toml; compare little-canary --version against GitHub Releases and PyPI for the published build.

Metadata

Release files for little-canary 0.3.10

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

Source distribution (sdist)

Source distribution for little-canary 0.3.10
File Size Uploaded
little_canary-0.3.10.tar.gz 116.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for little-canary 0.3.10
File Interpreter ABI Platform
little_canary-0.3.10-py3-none-any.whl Python 3 none any Details

Total release size: 183.1 kB

Release files / little_canary-0.3.10.tar.gz

Download URL little_canary-0.3.10.tar.gz
Size 116.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4470ffe495bc52823bfce79d84167a95746b13298911dc7c9ea473aaacdea178
BLAKE2b-256 checksum
How to use checksums
b05fcf8ca8940342a1b1712affff1caf462355e95df982d20b9b36700597b08d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 27, 2026.

Transparency log

Release files / little_canary-0.3.10-py3-none-any.whl

Download URL little_canary-0.3.10-py3-none-any.whl
Size 66.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b065cc536f2764ec86eb1870359abe7343d51ee02d4dd51406f7f7516d9a486
BLAKE2b-256 checksum
How to use checksums
b90a583e46e4e2d17a3cf8738229a7716dba9b0b92dd8ebe3e3da7dc341d089a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

2 release files

0.4.0

2 release files

This release

0.3.10 This release

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

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