Cisco AI Defense middleware for LangChain agents — runtime security inspection of LLM inputs/outputs and tool/MCP calls
Project description
langchain-cisco-aidefense
LangChain agent middleware for Cisco AI Defense, providing runtime security inspection of LLM inputs/outputs and tool/MCP calls.
Detects prompt injection, jailbreaks, PII leakage, toxic content, and unsafe tool usage — directly within the LangChain agent loop.
Installation
pip install langchain-cisco-aidefense
Middleware Overview
Four middleware implementations are provided:
LLM Inspection (before_model / after_model)
| Middleware | Built on | Best for |
|---|---|---|
AIDefenseMiddleware |
ChatInspectionClient |
New integrations — lightweight, no global state |
AIDefenseAgentsecMiddleware |
agentsec LLMInspector |
When you need agentsec's retry/backoff machinery |
Tool / MCP Inspection (wrap_tool_call)
| Middleware | Built on | Best for |
|---|---|---|
AIDefenseToolMiddleware |
MCPInspectionClient |
New integrations — tool/MCP call inspection |
AIDefenseAgentsecToolMiddleware |
agentsec MCPInspector |
When you need agentsec's retry/backoff machinery |
Quick Start
pip install langchain-cisco-aidefense langchain-openai
from aidefense_langchain import AIDefenseMiddleware
from langchain.agents import create_agent
agent = create_agent(
model="openai:gpt-4.1",
tools=[get_weather],
middleware=[
AIDefenseMiddleware(
api_key="your-cisco-ai-defense-api-key",
region="us-west-2",
mode="enforce",
),
],
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})
LLM Inspection
AIDefenseMiddleware (Recommended)
Uses ChatInspectionClient directly. Self-contained configuration, no global state, no monkey-patching.
from aidefense_langchain import AIDefenseMiddleware
from langchain.agents import create_agent
agent = create_agent(
model="openai:gpt-4.1",
tools=[get_weather],
middleware=[
AIDefenseMiddleware(
api_key="your-api-key",
region="us-west-2",
mode="enforce", # "enforce" | "monitor" | "off"
fail_open=True,
),
],
)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
required | Cisco AI Defense API key |
region |
str |
"us-west-2" |
AI Defense region ("us-west-2", "eu-central-1", "ap-northeast-1") |
mode |
str |
"enforce" |
"enforce" (block), "monitor" (log only), "off" |
fail_open |
bool |
True |
Allow on inspection API errors |
timeout |
int |
30 |
Inspection timeout in seconds |
rules |
list |
None |
Rules to enable (e.g. ["PII", "Prompt Injection"]) |
user |
str |
None |
User identity for audit |
src_app |
str |
None |
Source application name |
on_violation |
callable |
None |
(InspectResponse, direction) -> None callback |
How it works
User message
|
v
+--------------------------------------------------+
| before_model hook |
| -> ChatInspectionClient.inspect_conversation() |
| -> if not safe and mode="enforce": jump_to=end |
+--------------------------------------------------+
|
v
LLM call
|
v
+--------------------------------------------------+
| after_model hook |
| -> ChatInspectionClient.inspect_conversation() |
| -> if not safe and mode="enforce": jump_to=end |
+--------------------------------------------------+
|
v
Agent response
AIDefenseAgentsecMiddleware
Uses agentsec's LLMInspector — gets retry with exponential backoff and fail-open semantics.
from aidefense_langchain import AIDefenseAgentsecMiddleware
from langchain.agents import create_agent
agent = create_agent(
model="openai:gpt-4.1",
tools=[get_weather],
middleware=[
AIDefenseAgentsecMiddleware(
mode="enforce",
api_key="your-api-key",
endpoint="https://us.api.inspect.aidefense.security.cisco.com",
retry_total=3,
retry_backoff=1.0,
),
],
)
Do not call
agentsec.protect()when using middleware. The middleware handles all inspection directly. Callingprotect()would activate monkey-patching on the underlying LLM SDK, causing every request to be inspected twice — once by the patched SDK and once by the middleware — doubling latency and API calls with no security benefit.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode |
str |
"enforce" |
"enforce", "monitor", or "off" |
api_key |
str |
from state/env | AI Defense API key |
endpoint |
str |
from state/env | AI Defense API endpoint |
fail_open |
bool |
True |
Allow on inspection errors |
timeout_ms |
int |
from state | Timeout in milliseconds |
retry_total |
int |
1 |
Retry attempts |
retry_backoff |
float |
0.0 |
Backoff factor in seconds |
rules |
list |
None |
Inspection rules |
user |
str |
None |
User identity |
src_app |
str |
None |
Source application name |
on_violation |
callable |
None |
(Decision, direction) -> None callback |
Tool / MCP Inspection
AIDefenseToolMiddleware (Recommended for tools)
Uses MCPInspectionClient to inspect tool call requests (name + arguments) and tool call results.
from aidefense_langchain import AIDefenseMiddleware, AIDefenseToolMiddleware
from langchain.agents import create_agent
agent = create_agent(
model="openai:gpt-4.1",
tools=[search_db, send_email],
middleware=[
AIDefenseMiddleware(api_key="your-key", mode="enforce"),
AIDefenseToolMiddleware(api_key="your-key", mode="enforce"),
],
)
AIDefenseAgentsecToolMiddleware
Uses agentsec's MCPInspector with retry, backoff, and fail-open support.
from aidefense_langchain import AIDefenseAgentsecMiddleware, AIDefenseAgentsecToolMiddleware
agent = create_agent(
model="openai:gpt-4.1",
tools=[read_file, execute_query],
middleware=[
AIDefenseAgentsecMiddleware(mode="enforce", api_key="your-key"),
AIDefenseAgentsecToolMiddleware(mode="enforce", api_key="your-key"),
],
)
Tool Middleware Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
required / from env | Cisco AI Defense API key |
region |
str |
"us-west-2" |
AI Defense region (ChatClient variant only) |
mode |
str |
"enforce" |
"enforce", "monitor", or "off" |
fail_open |
bool |
True |
Allow on inspection API errors |
inspect_requests |
bool |
True |
Inspect tool call requests before execution |
inspect_responses |
bool |
True |
Inspect tool results after execution |
on_violation |
callable |
None |
Violation callback |
How tool inspection works
Tool call (from LLM)
|
v
+--------------------------------------------------+
| wrap_tool_call -- PRE-CALL inspection |
| -> MCPInspectionClient.inspect_tool_call() |
| -> if not safe and mode="enforce": return block |
+--------------------------------------------------+
|
v
Tool executes
|
v
+--------------------------------------------------+
| wrap_tool_call -- POST-CALL inspection |
| -> MCPInspectionClient.inspect_response() |
| -> if not safe and mode="enforce": return block |
+--------------------------------------------------+
|
v
Tool result returned to agent
This covers all tool types:
- LangChain tools (
@tooldecorated functions) - MCP tools registered via LangChain's MCP integration
- Any tool executed through the agent's tool node
Environment Variables
The middleware can also be configured via environment variables (used by from_env() class methods):
export AIDEFENSE_API_KEY=your-api-key
export AIDEFENSE_REGION=us-west-2
export AIDEFENSE_MODE=enforce
export AIDEFENSE_FAIL_OPEN=true
export AIDEFENSE_TIMEOUT=30
from aidefense_langchain import AIDefenseMiddleware
middleware = AIDefenseMiddleware.from_env()
Comparison
| Criteria | AIDefenseMiddleware |
AIDefenseAgentsecMiddleware |
|---|---|---|
| No global state / side effects | Yes | No (uses _state) |
| Self-contained config | Yes | Yes (pass explicitly) |
| Built-in retry + backoff | Via Config |
Custom |
| Built-in fail-open | In middleware | In inspector |
inspect_prompt / inspect_response |
Yes | No (inspect_conversation only) |
| Dependency footprint | Lighter (aidefense.runtime) |
Heavier (aidefense.runtime.agentsec) |
Recommendation: Use AIDefenseMiddleware for new projects. Use AIDefenseAgentsecMiddleware when you need agentsec's retry/backoff machinery.
Enforcement Modes
| Mode | Behavior |
|---|---|
enforce |
Block violations — agent returns a "blocked" message via jump_to: "end" |
monitor |
Log violations and invoke on_violation callback; never blocks |
off |
Skip inspection entirely |
Fail-Open Behavior
When fail_open=True (default) and the AI Defense inspection API is unreachable:
- The request is allowed to proceed
- A warning is logged
When fail_open=False:
- The request is blocked (or an exception is raised)
Examples
| # | File | Description |
|---|---|---|
| 1 | 01_chat_client_enforce.py |
ChatClient middleware — enforce mode (block violations) |
| 2 | 02_chat_client_monitor.py |
ChatClient middleware — monitor mode with violation callback |
| 3 | 03_chat_client_with_rules.py |
ChatClient middleware — specific rules (PII, Prompt Injection) |
| 4 | 04_agentsec_enforce.py |
Agentsec middleware — enforce mode with retry config |
| 5 | 05_composed_middleware.py |
AI Defense + custom logging middleware composed together |
| 6 | 06_side_by_side.py |
Same request through both middleware — side-by-side comparison |
| 7 | 07_tool_inspection_enforce.py |
Tool inspection — LLM + tool call inspection combined |
| 8 | 08_tool_inspection_agentsec.py |
Agentsec tool inspection — MCPInspector with retry |
Development
git clone https://github.com/cisco-ai-defense/ai-defense-langchain-middleware.git
cd ai-defense-langchain-middleware
pip install -e ".[dev,examples]"
pytest
License
Apache-2.0 — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_cisco_aidefense-1.0.0.tar.gz.
File metadata
- Download URL: langchain_cisco_aidefense-1.0.0.tar.gz
- Upload date:
- Size: 23.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
602b20a8e1c692dd8c99841493fe4b27e28408095c8938fcdd1b80d35aeb678c
|
|
| MD5 |
d8bc90f7ef11e34147555ffde46b73af
|
|
| BLAKE2b-256 |
dd2b8abb7e3ace1fb19b344b34e3ea855ba18905dcb042efb923666d1adf001b
|
Provenance
The following attestation bundles were made for langchain_cisco_aidefense-1.0.0.tar.gz:
Publisher:
release.yml on cisco-ai-defense/ai-defense-langchain-middleware
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_cisco_aidefense-1.0.0.tar.gz -
Subject digest:
602b20a8e1c692dd8c99841493fe4b27e28408095c8938fcdd1b80d35aeb678c - Sigstore transparency entry: 1161761352
- Sigstore integration time:
-
Permalink:
cisco-ai-defense/ai-defense-langchain-middleware@df62daa7cd74f2d3e522d35562dcf7d75b264672 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cisco-ai-defense
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@df62daa7cd74f2d3e522d35562dcf7d75b264672 -
Trigger Event:
push
-
Statement type:
File details
Details for the file langchain_cisco_aidefense-1.0.0-py3-none-any.whl.
File metadata
- Download URL: langchain_cisco_aidefense-1.0.0-py3-none-any.whl
- Upload date:
- Size: 24.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e4bfff61c9389cba477f97e93f80d060a7f883a65b2bb06092caa2c293de682
|
|
| MD5 |
85b691b7eb0d9142af12aa867792744e
|
|
| BLAKE2b-256 |
4c4812e5117b96732a649bcd8945d677176cb7d48c8fa6d36c3dcbd4c59c3058
|
Provenance
The following attestation bundles were made for langchain_cisco_aidefense-1.0.0-py3-none-any.whl:
Publisher:
release.yml on cisco-ai-defense/ai-defense-langchain-middleware
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_cisco_aidefense-1.0.0-py3-none-any.whl -
Subject digest:
4e4bfff61c9389cba477f97e93f80d060a7f883a65b2bb06092caa2c293de682 - Sigstore transparency entry: 1161761484
- Sigstore integration time:
-
Permalink:
cisco-ai-defense/ai-defense-langchain-middleware@df62daa7cd74f2d3e522d35562dcf7d75b264672 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cisco-ai-defense
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@df62daa7cd74f2d3e522d35562dcf7d75b264672 -
Trigger Event:
push
-
Statement type: