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.1.tar.gz (75.5 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.1-py3-none-any.whl (31.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: shieldops_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 75.5 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.1.tar.gz
Algorithm Hash digest
SHA256 3a97fd2c62f5576f1c38c8d96929b3938a8b4e0cbd1d33094ee80995d0f991b8
MD5 3cd2ba0293c0eecb2b2ec36a8eb70921
BLAKE2b-256 d3a24c56e03ebafc455655718b28fa78e9d6452fe2b112a0baa606e8af381009

See more details on using hashes here.

Provenance

The following attestation bundles were made for shieldops_sdk-0.1.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: shieldops_sdk-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 31.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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0c246bb8501834bddf32b7ef033456849c11c8cdc7b71a6cb1da1105be48a42b
MD5 73bc51435480806fd44076571ecd732f
BLAKE2b-256 42755f923c3de87e89dfb17b48506ceaead7df81f512976524eb47510ac9bb75

See more details on using hashes here.

Provenance

The following attestation bundles were made for shieldops_sdk-0.1.1-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