Skip to main content

canary-ops-sdk

The Operating System for AI Security — Python SDK for monitoring, securing, and auditing every AI agent and LLM application in production.

Zero-dependency telemetry, redaction, and firewall SDK. Works with any Python LLM library.

PyPI Python


Install

pip install canary-ops-sdk

No runtime dependencies. Python 3.8+.


Quick start

from canary_ops import Canary

canary = Canary(
    api_key="sk-canary-...",   # from your Canary dashboard
    agent_id="my-agent",
)

# Manual tracking
canary.track_prompt("What is the capital of France?", model="gpt-4o")
canary.track_response("Paris.", model="gpt-4o", tokens_in=10, tokens_out=3)
canary.track_tool_call("web_search", {"query": "Paris"}, {"results": [...]})

canary.flush()  # or call shutdown() at process exit

OpenAI instrumentation

from openai import OpenAI
from canary_ops import Canary

canary = Canary(api_key="sk-canary-...", agent_id="my-agent")
client = canary.wrap_openai(OpenAI())

# All chat completions are now tracked automatically
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)

Streaming is also supported — just pass stream=True.


Anthropic instrumentation

import anthropic
from canary_ops import Canary

canary = Canary(api_key="sk-canary-...", agent_id="my-agent")
client = canary.wrap_anthropic(anthropic.Anthropic())

response = client.messages.create(
    model="claude-opus-4-5",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=256,
)

Prompt firewall

from canary_ops import Canary, CanaryBlockedError, ScanOptions

canary = Canary(api_key="sk-canary-...", agent_id="my-agent")

# scan() — returns a ScanResult, never raises
result = canary.scan(user_prompt, ScanOptions(remote=False))
if not result.allowed:
    return "I can't help with that."

# guard() — raises CanaryBlockedError if the prompt is blocked
try:
    safe_prompt = canary.guard(user_prompt)
except CanaryBlockedError as e:
    print(f"Blocked: {e.scan_result.threats}")

Output scanning

# Scan a response for leaked secrets, PII, or exfiltration
from canary_ops import ScanResponseOptions

result = canary.scan_response(
    llm_output,
    ScanResponseOptions(throw_on_unsafe=True),
)

Canary tokens

# Plant a decoy credential in your agent's context
token = canary.plant_token()
system_prompt = f"Company API key: {token.token_value}\n{your_context}"

# If the token appears in any response, Canary fires a data_exfiltration alert
result = canary.scan_response(response_text)

RAG context scanning

from canary_ops import ScanContextOptions

docs = retriever.get_relevant_documents(query)
results = canary.scan_context(
    [d.page_content for d in docs],
    ScanContextOptions(concurrency=5),
)
safe_docs = [d for d, r in zip(docs, results) if r.allowed]

Configuration reference

from canary_ops import Canary, GuardConfig, RedactionConfig, RetryConfig

canary = Canary(
    api_key="sk-canary-...",
    agent_id="my-agent",
    # Privacy
    capture_content=True,          # set False for metadata-only mode
    max_content_length=10_000,     # truncate long prompts
    redaction=RedactionConfig(
        secrets=True,              # strip API keys, tokens, private keys
        pii=True,                  # strip emails, phones, SSNs, credit cards
        mode="mask",               # "mask" | "hash" | "remove"
    ),
    sample_rate=0.5,               # only send 50% of events
    # Firewall
    guard=GuardConfig(
        local=True,                # run in-process heuristics
        remote=True,               # call the remote deep scanner
        block_on_local=True,       # short-circuit on high-confidence local hit
        responses=False,           # auto-scan every LLM response
    ),
    fail_open=True,                # allow prompts if the remote scanner is unreachable
    # Resilience
    timeout_ms=10_000,
    retry=RetryConfig(retries=3, backoff_ms=250),
    # Batching
    flush_interval_ms=5_000,       # drain queue every 5 s
    max_batch_size=20,             # flush immediately when queue hits 20
    # Hooks
    before_send=lambda event: event,   # inspect/mutate/drop events
    on_error=lambda exc: print(exc),   # custom error handler
    # Tagging
    environment="production",
    release="v1.2.3",
    debug=False,
)

Error reference

Exception When it's raised
CanaryBlockedError guard() or scan_response(..., throw_on_unsafe=True) when the firewall blocks
CanaryApiError plant_token() when the API call fails
CanaryNotInitializedError Calling SDK methods before Canary(...) is constructed

CanaryBlockedError carries a .scan_result attribute with the full ScanResult.


Async support

All wrapper patching detects whether the underlying client's create method is a coroutine and patches it with an async wrapper automatically. The Canary client itself is thread-safe; background flushing runs on a daemon thread.


License

MIT © CryptoSuess & Txnchi

Metadata

Release files for canary-ops-sdk 0.2.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 canary-ops-sdk 0.2.0
File Size Uploaded Provenance Actions
canary_ops_sdk-0.2.0.tar.gz 23.7 kB Without provenance Details for canary_ops_sdk-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for canary-ops-sdk 0.2.0
File Interpreter ABI Platform Actions
canary_ops_sdk-0.2.0-py3-none-any.whl Python 3 none any Details for canary_ops_sdk-0.2.0-py3-none-any.whl

Total release size: 44.9 kB

Release files / canary_ops_sdk-0.2.0.tar.gz

Download URL canary_ops_sdk-0.2.0.tar.gz
Size 23.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2755a679155d6d2ac96e665415e0cf7003b74cbb16998656c54267a519437c8f
BLAKE2b-256 checksum
How to use checksums
b828167f06d641bb5573f00f130fa50927190f9463df374434d5ffb4b42d0991
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release files / canary_ops_sdk-0.2.0-py3-none-any.whl

Download URL canary_ops_sdk-0.2.0-py3-none-any.whl
Size 21.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f8e2f581e7c6c43613d8cd8528d1e0ccaa73be4df9bb86184f3d96302303b497
BLAKE2b-256 checksum
How to use checksums
c52971b1fd6571324f990f842b32b929253694fc1587ea5e5f581327d3895dbc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Security for canary-ops-sdk 0.2.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.2.0 This release

2 release files No 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