Skip to main content

Cisco AI Defense plugin for Google ADK — native callback-based LLM and MCP inspection

Project description

ai-defense-google-adk

Cisco AI Defense plugin for Google ADK — native callback-based LLM and MCP tool inspection.

This package integrates Cisco AI Defense runtime inspection directly into the ADK Runner lifecycle using a BasePlugin and per-agent callbacks. It supports both LLM prompt/response inspection and MCP tool call inspection, with monitor and enforce modes, plus optional violation callbacks and structured enforcement metadata.

Use Cases

  • Runtime protection for Gemini calls: Inspect user prompts before model calls and model outputs after generation, then allow or block based on policy (Monitor or Enforce).
  • Tool and MCP call inspection: Inspect tool call requests before execution and tool responses after execution, and block unsafe tool behavior in Enforce mode with clear metadata.
  • Auditable decision trace and alerts: Capture decision context (action, severity, classifications, request_id/event_id) and optionally trigger an on_violation callback for monitoring and incident response.

Prerequisites

Installation

pip install cisco-aidefense-google-adk

Quick Start (one-liner)

The fastest way to add AI Defense to any ADK agent:

from aidefense_google_adk import defend

# Defend an agent (attaches all 4 callbacks automatically)
agent = defend(agent, mode="enforce")

# Or get a plugin for the App
plugin = defend(mode="enforce")
app = App(name="my_app", root_agent=agent, plugins=[plugin])

Set the AI_DEFENSE_API_KEY environment variable (and AI_DEFENSE_MCP_API_KEY for tool inspection) and you're done.

Environment Variables

Variable Used by Description
AI_DEFENSE_API_KEY Raw client (LLM) API key for prompt/response inspection
AI_DEFENSE_MCP_API_KEY Raw client (MCP) API key for tool call inspection
AI_DEFENSE_RUNTIME_URL Raw client Custom runtime endpoint URL
AI_DEFENSE_MODE Raw client Default mode (monitor / enforce / off)
AI_DEFENSE_API_MODE_LLM_API_KEY Inspector (LLM) API key for LLM inspection via agentsec
AI_DEFENSE_API_MODE_MCP_API_KEY Inspector (MCP) API key for MCP inspection via agentsec
AI_DEFENSE_API_MODE_LLM_ENDPOINT Inspector (LLM) Endpoint for LLM inspection
AI_DEFENSE_API_MODE_MCP_ENDPOINT Inspector (MCP) Endpoint for MCP inspection

To see inspection logs without configuring Python logging:

from aidefense_google_adk import configure_logging
configure_logging()

Plugin (Tier 2) — Global, applies to all agents

import os
from google.adk.agents import LlmAgent
from google.adk.apps import App
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService

from aidefense_google_adk import CiscoAIDefensePlugin

agent = LlmAgent(model="gemini-2.5-flash", name="assistant", instruction="...")

# API key auto-resolves from AI_DEFENSE_API_KEY env var
app = App(
    name="my_app",
    root_agent=agent,
    plugins=[
        CiscoAIDefensePlugin(mode="enforce"),
    ],
)
runner = Runner(app=app, session_service=InMemorySessionService())

Agent Callbacks (Tier 1) — Per-agent

from aidefense_google_adk import make_aidefense_callbacks

# API key auto-resolves from AI_DEFENSE_API_KEY env var
cbs = make_aidefense_callbacks(mode="enforce")

agent = LlmAgent(model="gemini-2.5-flash", name="assistant", instruction="...")
cbs.apply_to(agent)  # wires all 4 callbacks in one call

Modes

Mode Behavior
monitor Inspect all traffic, log violations, never block (default)
enforce Inspect all traffic, block requests/responses that violate policy
off Skip inspection entirely

Modes can be set globally or per-channel:

CiscoAIDefensePlugin(
    mode="monitor",          # default for both
    llm_mode="enforce",      # override for LLM only
    mcp_mode="off",          # override for tools only
)

Callbacks Covered

ADK Callback Raw Client Inspector What it inspects
before_model_callback ChatInspectionClient.inspect_prompt() LLMInspector.ainspect_conversation() User prompt before LLM call
after_model_callback ChatInspectionClient.inspect_response() LLMInspector.ainspect_conversation() LLM response after generation
before_tool_callback MCPInspectionClient.inspect() MCPInspector.ainspect_request() Tool call request before execution
after_tool_callback MCPInspectionClient.inspect() MCPInspector.ainspect_response() Tool call result after execution

Violation Callback

Receive notification of every violation regardless of mode:

def handle_violation(result):
    print(f"Violation: {result.action} / {result.severity}")

CiscoAIDefensePlugin(
    mode="monitor",
    on_violation=handle_violation,
)

Enforced Tool Block Payloads

In enforce mode, blocked tool callbacks keep the legacy error field and also return structured metadata when Cisco AI Defense provides it:

{
    "error": "Tool response from 'query_database' blocked by Cisco AI Defense policy.",
    "blocked": True,
    "action": "Block",
    "stage": "tool_response",
    "severity": "HIGH",
    "classifications": ["PRIVACY_VIOLATION"],
    "rules": [{"rule_name": "PII", "classification": "PRIVACY_VIOLATION"}],
    "event_id": "...",
    "request_id": "...",
}

This makes it easier to audit or render enforced tool decisions without reconstructing the decision from logs.

Inspector-based Integration (agentsec)

In addition to the raw-client modules above, this package provides Inspector-based variants that use LLMInspector / MCPInspector from the agentsec SDK layer. These add:

  • Automatic retry with exponential backoff
  • Fail-open / fail-closed semantics
  • Structured Decision objects with severity, classifications, rules, and event IDs
  • Auto-resolution of API keys and endpoints from environment variables

AgentsecPlugin (Tier 2) — Global, applies to all agents

from aidefense_google_adk import AgentsecPlugin

# API key auto-resolves from AI_DEFENSE_API_MODE_LLM_API_KEY env var
app = App(
    name="my_app",
    root_agent=agent,
    plugins=[
        AgentsecPlugin(
            mode="enforce",
            fail_open=True,
            retry_total=3,
            retry_backoff=0.5,
        ),
    ],
)
runner = Runner(app=app, session_service=InMemorySessionService())

Agentsec Callbacks (Tier 1) — Per-agent

from aidefense_google_adk import make_agentsec_callbacks

# API key auto-resolves from AI_DEFENSE_API_MODE_LLM_API_KEY env var
cbs = make_agentsec_callbacks(
    mode="enforce",
    fail_open=True,
)

agent = LlmAgent(
    model="gemini-2.5-flash",
    name="assistant",
    instruction="...",
    before_model_callback=cbs.before_model,
    after_model_callback=cbs.after_model,
    before_tool_callback=cbs.before_tool,
    after_tool_callback=cbs.after_tool,
)

Violation Callback with Decision Objects

The Inspector-based modules pass Decision objects (not raw InspectResponse) to the on_violation callback:

def handle_violation(decision):
    print(f"Action: {decision.action}")
    print(f"Severity: {decision.severity}")
    print(f"Classifications: {decision.classifications}")
    print(f"Rules: {decision.rules}")
    print(f"Event ID: {decision.event_id}")

AgentsecPlugin(
    mode="monitor",
    on_violation=handle_violation,
)

Which Approach Should I Use?

Feature Raw Client (CiscoAIDefensePlugin) Inspector (AgentsecPlugin)
Retry with backoff Via Config(retry_config={...}) (HTTP-level) Built-in application-level (retry_total, retry_backoff)
Fail-open / fail-closed Configurable via fail_open param Configurable via fail_open param
Violation data InspectResponse (.is_safe, .action, .severity, .classifications, .rules, .event_id) Decision (.allows(), .severity, .classifications, .rules, .event_id)
API key resolution AI_DEFENSE_API_KEY (LLM) + AI_DEFENSE_MCP_API_KEY (MCP) AI_DEFENSE_API_MODE_LLM_API_KEY + AI_DEFENSE_API_MODE_MCP_API_KEY
Custom endpoint Via Config object (full HTTP/TLS/pool control) Via endpoint string param
Best for Full control over HTTP config (TLS, pool, headers) Simpler API with application-level retry

Additional agentsec Approaches

Monkey-patching with agentsec.protect()

Two lines of code before importing ADK — all LLM and MCP calls are transparently inspected:

from aidefense.runtime import agentsec

agentsec.protect(
    api_mode={
        "llm": {"mode": "monitor"},
        "mcp": {"mode": "monitor"},
    },
)

# Now import and use ADK as usual — calls are already patched
from google.adk.agents import LlmAgent

See examples/agentsec_protect.py for a complete runnable example.

Manual Inspector Wiring

Wire the agentsec inspectors into ADK's per-agent callback hooks directly for maximum customization:

from aidefense.runtime.agentsec.inspectors import LLMInspector, MCPInspector

llm_inspector = LLMInspector()
mcp_inspector = MCPInspector()

async def before_model_callback(*, callback_context, llm_request):
    decision = await llm_inspector.ainspect_conversation(messages, metadata)
    if not decision.allows():
        return blocked_response(decision.reasons)
    return None

agent = LlmAgent(
    model="gemini-2.5-flash",
    name="assistant",
    instruction="...",
    before_model_callback=before_model_callback,
    # ... other callbacks
)

See examples/agentsec_callbacks.py for a complete runnable example.

Running the agentsec Examples

pip install cisco-aidefense-google-adk[examples]
cd examples
cp .env.example .env    # fill in your API keys
python agentsec_plugin.py              # AgentsecPlugin (Tier 2)
python agentsec_plugin.py --callbacks  # make_agentsec_callbacks (Tier 1)
python agentsec_protect.py             # monkey-patching approach
python agentsec_callbacks.py           # manual Inspector wiring

Resources

Development

pip install -e ".[dev]"
pytest

License

Distributed under the Apache 2.0 License. See LICENSE for more information.

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

cisco_aidefense_google_adk-1.0.0.tar.gz (22.7 kB view details)

Uploaded Source

Built Distribution

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

cisco_aidefense_google_adk-1.0.0-py3-none-any.whl (31.1 kB view details)

Uploaded Python 3

File details

Details for the file cisco_aidefense_google_adk-1.0.0.tar.gz.

File metadata

File hashes

Hashes for cisco_aidefense_google_adk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 3fe2cf0ea529c76f649c64f63c96bd8fb0d9b82297395891d99a16361134d8b7
MD5 fc09901d085f5a2a7d7954604865f47f
BLAKE2b-256 44794fbe7227c075c5ca80b48b6acd18cd32544a297c91d865671355e56cbbb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for cisco_aidefense_google_adk-1.0.0.tar.gz:

Publisher: release.yml on cisco-ai-defense/ai-defense-google-adk

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

File details

Details for the file cisco_aidefense_google_adk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cisco_aidefense_google_adk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0a2d61b113a0506ab3ea6248e26c85b416ee7c846e977c8b1c552417b9476c55
MD5 83142839744e96bd5ba7d9ee755573ea
BLAKE2b-256 700a7f8a67d439b435559f428e0918b0751b60730ab0322465670bebdffbaaa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cisco_aidefense_google_adk-1.0.0-py3-none-any.whl:

Publisher: release.yml on cisco-ai-defense/ai-defense-google-adk

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