Skip to main content

AI Security Control Plane SDK — intercept and govern AI agent tool calls

Project description

shieldops-sdk

AI Security Control Plane SDK — intercept and govern AI agent tool calls.

Local-first by default: zero network attempts, zero accounts, zero secrets required to get started. Opt in to remote telemetry only when you're ready.

Install

pip install shieldops-sdk

With framework integrations:

pip install "shieldops-sdk[langchain]"
pip install "shieldops-sdk[crewai]"
pip install "shieldops-sdk[llamaindex]"

Your first interception (local mode — no network, no API key)

from shieldops_sdk import ShieldOpsConfig, ShieldOpsInterceptor, SDKMode

# Default config: local mode, no network calls, no API key required.
interceptor = ShieldOpsInterceptor(ShieldOpsConfig(mode=SDKMode.ENFORCE))

decision = interceptor.check("delete_database", {"db": "users"})
# Raises ShieldOpsDeniedError — delete_database is a default-blocked pattern.

ShieldOpsConfig() with no arguments runs entirely in-process:

  • No network callsinterceptor.check() evaluates against an in-memory policy catalogue.
  • No API key required — the SDK never tries to reach api.shieldops.io unless you explicitly opt in.
  • AUDIT mode (default) observes every call without blocking; ENFORCE mode raises ShieldOpsDeniedError on policy violations.

Connected mode (opt-in remote telemetry)

from shieldops_sdk import ShieldOpsConfig, ShieldOpsInterceptor, SDKMode, SDKTelemetry

config = ShieldOpsConfig(
    api_key="sk-...",
    mode=SDKMode.ENFORCE,
    telemetry=SDKTelemetry.REMOTE,   # opt in — required for network calls
)
interceptor = ShieldOpsInterceptor(config)

# async_check() POSTs to the ShieldOps backend, falls back to local on errors
decision = await interceptor.async_check("search_database", {"query": "SELECT * FROM users"})

Three telemetry destinations:

SDKTelemetry Network behavior Requires
LOCAL (default) None — in-process only
REMOTE POSTs to ShieldOps backend api_key set
OTLP Routes to your OpenTelemetry collector OTEL collector

⚠ Breaking change in 0.1.0 vs prerelease builds

Previously, setting api_key alone caused async_check() to POST to the ShieldOps backend implicitly. Starting in 0.1.0, network calls require BOTH:

  • api_key set, AND
  • telemetry=SDKTelemetry.REMOTE (explicit opt-in)

If you set only api_key without telemetry, the SDK falls back to local evaluation. This is a deliberately safer default — no implicit network on credentials alone.

Extending the policy catalogue

from shieldops_sdk import ShieldOpsConfig

config = ShieldOpsConfig(
    extra_blocked_patterns={"export_customer_data", "bulk_email_send"},
    extra_high_risk_patterns={"wire_transfer", "approve_refund"},
)

Extras are merged with the SDK's built-in defaults at interceptor construction time. Each interceptor instance gets its own fresh copy — mutations don't leak between instances.

Framework integrations

LangChain

from shieldops_sdk import ShieldOpsConfig, SDKMode
from shieldops_sdk.integrations.langchain import ShieldOpsCallbackHandler

handler = ShieldOpsCallbackHandler(ShieldOpsConfig(mode=SDKMode.ENFORCE))
agent.invoke({"input": "..."}, config={"callbacks": [handler]})

CrewAI

from shieldops_sdk import ShieldOpsConfig, SDKMode
from shieldops_sdk.integrations.crewai import ShieldOpsCrewAIWrapper

wrapper = ShieldOpsCrewAIWrapper(ShieldOpsConfig(mode=SDKMode.ENFORCE))
secured_crew = wrapper.wrap_crew(my_crew)

LlamaIndex

from shieldops_sdk import ShieldOpsConfig, SDKMode
from shieldops_sdk.integrations.llamaindex import ShieldOpsToolWrapper

wrapper = ShieldOpsToolWrapper(ShieldOpsConfig(mode=SDKMode.ENFORCE))
wrapper.on_tool_start("search_tool", {"query": "find users"})

API client (connected mode only)

from shieldops_sdk import ShieldOpsClient

with ShieldOpsClient(api_key="sk-...") as client:
    investigations = client.investigations.list(limit=10)
    for inv in investigations.items:
        print(inv.investigation_id, inv.status)

Experimental integrations

shieldops_sdk.experimental.* ships integrations whose surface may change without notice between minor releases. Importing anything from this namespace emits a one-time UserWarning.

# Emits a UserWarning on first import
from shieldops_sdk.experimental.autogen import ShieldOpsAutoGenWrapper
from shieldops_sdk.experimental.openai_agents import ShieldOpsOpenAIAgentsHandler

If you depend on these, pin a specific SDK version. Stable integrations live under shieldops_sdk.integrations.

Configuration at a glance

Env var Default Description
SHIELDOPS_API_KEY "" API key for authentication (only required for REMOTE telemetry)
SHIELDOPS_ENDPOINT https://api.shieldops.io ShieldOps backend URL
SHIELDOPS_MODE audit audit (log only) or enforce (block risky calls)

See the Configuration Guide for the full list.

Modes vs Telemetry

mode and telemetry are independent axes:

  • mode — does the SDK block on policy violations? (AUDIT = observe; ENFORCE = raise)
  • telemetry — where do records of decisions go? (LOCAL, REMOTE, OTLP)

A blocked call in ENFORCE mode raises regardless of telemetry. A network POST happens only when telemetry=REMOTE and api_key is set. See tests/test_telemetry_modes.py for the locked behavior matrix.

Documentation

License

Apache 2.0

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

shieldops_sdk-0.1.2.tar.gz (81.7 kB view details)

Uploaded Source

Built Distribution

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

shieldops_sdk-0.1.2-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

File details

Details for the file shieldops_sdk-0.1.2.tar.gz.

File metadata

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

File hashes

Hashes for shieldops_sdk-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d9811f2546ceab264f05b6abd657e72a12c7c661c512483452df6792154140c6
MD5 a0f7c3ef6f0a9d6281571d3613ac0dda
BLAKE2b-256 1be4165c363e3fd5b9317be5e0ced2a960f8d4bfd2bbb2287f6bff76e424f7f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for shieldops_sdk-0.1.2.tar.gz:

Publisher: release.yml on shieldops-io/shieldops-sdk

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

File details

Details for the file shieldops_sdk-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: shieldops_sdk-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 34.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shieldops_sdk-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7b25e469cc85518461b80df926fea557c0ce899913336341de0d73d803270fe7
MD5 3ef0611f31fc033ae488056482f88d4a
BLAKE2b-256 3199978d23bec77b4de7006279b7ab66432bfd7f74e7dfe6cbe2978830f6830c

See more details on using hashes here.

Provenance

The following attestation bundles were made for shieldops_sdk-0.1.2-py3-none-any.whl:

Publisher: release.yml on shieldops-io/shieldops-sdk

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