Skip to main content

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.

Metadata

Release files for cisco-aidefense-google-adk 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cisco-aidefense-google-adk 1.0.0
File Size Uploaded Provenance Actions
cisco_aidefense_google_adk-1.0.0.tar.gz 22.7 kB With provenance Details for cisco_aidefense_google_adk-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cisco-aidefense-google-adk 1.0.0
File Interpreter ABI Platform Actions
cisco_aidefense_google_adk-1.0.0-py3-none-any.whl Python 3 none any Details for cisco_aidefense_google_adk-1.0.0-py3-none-any.whl

Total release size: 53.9 kB

Release files / cisco_aidefense_google_adk-1.0.0.tar.gz

Download URL cisco_aidefense_google_adk-1.0.0.tar.gz
Size 22.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3fe2cf0ea529c76f649c64f63c96bd8fb0d9b82297395891d99a16361134d8b7
BLAKE2b-256 checksum
How to use checksums
44794fbe7227c075c5ca80b48b6acd18cd32544a297c91d865671355e56cbbb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 21, 2026.

Transparency log

Release files / cisco_aidefense_google_adk-1.0.0-py3-none-any.whl

Download URL cisco_aidefense_google_adk-1.0.0-py3-none-any.whl
Size 31.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0a2d61b113a0506ab3ea6248e26c85b416ee7c846e977c8b1c552417b9476c55
BLAKE2b-256 checksum
How to use checksums
700a7f8a67d439b435559f428e0918b0751b60730ab0322465670bebdffbaaa8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 21, 2026.

Transparency log

Security for cisco-aidefense-google-adk 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cisco_aidefense_google_adk-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page