Skip to main content

The Operating System for AI Security — monitor, secure, and audit every AI agent and LLM application in production.

Project description

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

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

canary_ops_sdk-0.1.0.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

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

canary_ops_sdk-0.1.0-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file canary_ops_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: canary_ops_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.14

File hashes

Hashes for canary_ops_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 64c3a3c5d87a906c042fca84b82e2afc1876a7d813aa69b173f9731874198a5a
MD5 02ae9e3ab0c7f081b07f2d047661b688
BLAKE2b-256 fb123ee35ce9172f89098dce5c85ef814f2824ed3acdadedda7594a78fae5f7e

See more details on using hashes here.

File details

Details for the file canary_ops_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: canary_ops_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.14

File hashes

Hashes for canary_ops_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eec725b1e4c789cce6dcec253b57bee982a857787c905ef06d534f4a9d6af1d3
MD5 5e59b5d996720ff54c52de219c24c259
BLAKE2b-256 808e57637f78e767e1c6a1df1bc4a369d59e1030afa430d76751c1386d0e597e

See more details on using hashes here.

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