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

Uploaded Python 3

File details

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

File metadata

  • Download URL: shieldops_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 73.9 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.0.tar.gz
Algorithm Hash digest
SHA256 3ee9c040318e211483a00708ce445f0d8bd0a173b0d76cceb532adf4a303697a
MD5 19e024e1f910fdacfd3c9fb2904eacb0
BLAKE2b-256 dfa2cf67e3d53fcd9f00a0d05abc0abb601d678213591cd67bd7d2a46981fb0d

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: shieldops_sdk-0.1.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb2bee60f7d9ba170c2e3f743c6ff146d417d0726fb85d501f1d942ca60b50dc
MD5 95fa2f0af1e78a179484ca55ec45787f
BLAKE2b-256 c4c1f6c1eaa07edf90d0e90b248809d9f623a4e67930b09a8446dc3c9e1335b5

See more details on using hashes here.

Provenance

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