Skip to main content

Zero-trust runtime security layer for LLM agents - inspects prompts, responses, and tool calls in real time

Project description

๐Ÿ›ก๏ธ ShieldFlow

Zero-Trust Runtime Security for LLM Agents

Inspect prompts, responses, and tool calls in real time before they reach the model or external systems.

Installation โ€ข Quick Start โ€ข Features โ€ข Integrations โ€ข Documentation


Why ShieldFlow?

LLM agents are powerful but vulnerable. They can:

  • Leak sensitive data (PII, API keys, internal documents)
  • Be manipulated via prompt injection attacks
  • Execute malicious tool calls from compromised contexts

ShieldFlow acts as a runtime intrusion detection system (IDS) for your AI agents, providing:

โœ… Real-time inspection of all LLM traffic
โœ… Automatic PII detection and masking
โœ… Prompt injection attack detection (rule-based + Gemini AI)
โœ… Trust scoring with automatic tool revocation
โœ… Full observability via Datadog dashboards
โœ… Kafka/Flink streaming for enterprise scale


Installation

# Basic installation
pip install shieldflow

# With Datadog observability
pip install shieldflow[observability]

# With LangChain integration
pip install shieldflow[langchain]

# With CrewAI integration
pip install shieldflow[crewai]

# With Kafka/Flink streaming
pip install shieldflow[streaming]

# Everything
pip install shieldflow[all]

Quick Start

Basic Usage

from shieldflow import Inspector, DetectorSuite, TrustEngine, InMemoryTrustStore

# Initialize ShieldFlow
detectors = DetectorSuite()  # Auto-enables Gemini if GEMINI_API_KEY is set
trust_engine = TrustEngine(InMemoryTrustStore())
inspector = Inspector(detectors, trust_engine)

# Inspect a prompt before sending to LLM
result = inspector.inspect_prompt("session-123", user_prompt)

if result.allowed:
    # Safe to send - use redacted text if PII was found
    clean_prompt = result.redacted_text or user_prompt
    response = llm.generate(clean_prompt)
    
    # Inspect the response too
    response_result = inspector.inspect_response("session-123", response)
else:
    # Blocked - potential attack detected
    print(f"Blocked: {result.reason}")

Environment Variables

# Gemini AI Detection (recommended)
export GEMINI_API_KEY=your_gemini_api_key

# Datadog Observability
export DATADOG_API_KEY=your_datadog_api_key
export DATADOG_APP_KEY=your_datadog_app_key
export DD_SITE=us5.datadoghq.com  # Your Datadog region

# Kafka Streaming (optional)
export SHIELDFLOW_KAFKA_BOOTSTRAP=localhost:9092
export SHIELDFLOW_KAFKA_TOPIC=shieldflow.detections

CLI Commands

ShieldFlow includes a CLI for easy setup:

# Check your environment
shieldflow doctor

# Interactive setup wizard
shieldflow setup

# Set up Datadog dashboard and monitors
shieldflow setup datadog

# Generate docker-compose.yml for local stack
shieldflow setup docker

Features

๐Ÿ” Detection Suite

Detector Description Confidence
PII Detection SSN, credit cards, emails, phone numbers, AWS keys High
Prompt Injection "Ignore previous", "system override", embedded instructions High
High Entropy Detects potential data exfiltration (base64, hex dumps) Medium
Gemini AI Dynamic AI-based analysis for sophisticated attacks High

๐Ÿ“Š Trust Scoring

Each session starts with a trust score of 100. Risky events decrease the score:

Event Score Impact
PII detected -25
Prompt injection -40
High entropy response -20
Clean message +1 (capped)

Trust thresholds:

  • score < 60 โ†’ Disable non-idempotent tools
  • score < 30 โ†’ Block all tool calls, require human review

๐Ÿ› ๏ธ Tool & MCP Guarding

ShieldFlow inspects tool descriptions and outputs for injection attacks:

from shieldflow.integrations.langchain_callback import validate_tool_metadata

# Validate before registering tools
tools = [search_tool, calculator_tool]
issues = validate_tool_metadata(tools, inspector)

if issues:
    print(f"Dangerous tools detected: {issues}")

Integrations

LangChain

from langchain.chat_models import ChatOpenAI
from shieldflow.integrations.langchain_callback import ShieldFlowCallbackHandler

# Create callback handler
handler = ShieldFlowCallbackHandler(inspector, session_id="user-123")

# Attach to your chain
llm = ChatOpenAI(callbacks=[handler])
chain = create_your_chain(llm)

# All prompts and responses are automatically inspected
result = chain.invoke({"input": user_message})

CrewAI

from crewai import Agent, Crew, Task
from shieldflow.integrations.crewai_middleware import CrewAIMiddleware

# Wrap your crew with ShieldFlow
middleware = CrewAIMiddleware(inspector)

# Guarded kickoff - inspects prompts and responses
result = middleware.kickoff_guarded(
    crew=crew,
    inputs={"topic": user_input},
    session_id="crew-session-123"
)

Kafka/Flink Streaming

# Detections are automatically streamed when env vars are set
# SHIELDFLOW_KAFKA_BOOTSTRAP=localhost:9092
# SHIELDFLOW_KAFKA_TOPIC=shieldflow.detections

# Or configure manually
from shieldflow.event_bus import KafkaSink

sink = KafkaSink(bootstrap_servers="kafka:9092", topic="detections")
inspector = Inspector(detectors, trust_engine, event_sink=sink)

Datadog Observability

Automatic Setup

# Set your credentials
export DATADOG_API_KEY=your_api_key
export DATADOG_APP_KEY=your_app_key
export DD_SITE=us5.datadoghq.com

# Run setup
shieldflow setup datadog

This creates:

  • Dashboard with trust scores, detection counts, and flagged content log
  • Monitors for high block rates, low trust scores, and attack spikes

Metrics Sent

Metric Type Description
shieldflow.trust_score Gauge Current session trust score
shieldflow.blocks.total Gauge Cumulative blocked requests
shieldflow.masked.total Gauge Cumulative masked requests
shieldflow.detection.*.total Gauge Counts by detection type

Log Stream

All flagged prompts, tool descriptions, and outputs are logged with:

  • Original text (truncated)
  • Detection types
  • Action taken
  • Session ID

Docker Stack

For local development with Redis, Kafka, and Flink:

# Generate docker-compose.yml
shieldflow setup docker

# Start the stack
docker-compose up -d

# Services:
# - Redis:  localhost:6380
# - Kafka:  localhost:19092  
# - Flink:  http://localhost:8081

Using Redis for Trust Storage

import redis
from shieldflow.trust import TrustEngine, RedisTrustStore

r = redis.Redis(host="localhost", port=6380)
trust_engine = TrustEngine(RedisTrustStore(r))

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        Your Application                          โ”‚
โ”‚  (LangChain, CrewAI, Custom Agent)                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
                          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      ShieldFlow Inspector                        โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚  โ”‚ PII Detector โ”‚  โ”‚  Injection   โ”‚  โ”‚   Entropy    โ”‚           โ”‚
โ”‚  โ”‚              โ”‚  โ”‚  Detector    โ”‚  โ”‚   Detector   โ”‚           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚  โ”‚           Gemini AI Safety Detector              โ”‚           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚                          โ”‚                                       โ”‚
โ”‚                          โ–ผ                                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚  โ”‚              Trust Engine (Redis)                 โ”‚           โ”‚
โ”‚  โ”‚         Score: 100 โ†’ Decision: allow/block        โ”‚           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ–ผ               โ–ผ               โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚  Kafka   โ”‚    โ”‚ Datadog  โ”‚    โ”‚   LLM    โ”‚
    โ”‚ (stream) โ”‚    โ”‚ (observe)โ”‚    โ”‚ (if safe)โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

API Reference

Inspector

class Inspector:
    def inspect_prompt(
        self, 
        session_id: str, 
        prompt: str, 
        allow_masking: bool = True
    ) -> InspectionDecision:
        """Inspect a user prompt before sending to LLM."""
        
    def inspect_response(
        self, 
        session_id: str, 
        response: str
    ) -> InspectionDecision:
        """Inspect an LLM response before returning to user."""

InspectionDecision

@dataclass
class InspectionDecision:
    allowed: bool           # Whether to proceed
    redacted_text: str      # Text with PII masked (if any)
    detections: List[DetectionResult]  # What was found
    trust: TrustDecision    # Trust score info
    action: str             # "allow" | "allow_masked" | "block"
    reason: str             # Human-readable explanation

DetectorSuite

class DetectorSuite:
    def __init__(self, use_gemini: bool = None):
        """
        Initialize detectors.
        
        Args:
            use_gemini: Enable Gemini AI detection.
                       None = auto-detect from GEMINI_API_KEY env var
        """

Examples

See the examples/ directory for complete examples:

  • demo_pipeline.py - Basic detection demo
  • crewai_guarded_agent.py - CrewAI integration
  • langchain_guarded_agent.py - LangChain integration
  • flink_sql_example.sql - Flink SQL UDF usage

Contributing

Contributions are welcome! Please see our Contributing Guide.

# Development setup
git clone https://github.com/Enoch-015/ShieldFlow.git
cd ShieldFlow
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=shieldflow

License

MIT License - see LICENSE for details.


Security

Found a vulnerability? Please report it responsibly by emailing security@shieldflow.dev or opening a private security advisory on GitHub.


Built with โค๏ธ for safer AI agents

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

shieldflow-0.1.0.tar.gz (40.0 kB view details)

Uploaded Source

Built Distribution

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

shieldflow-0.1.0-py3-none-any.whl (34.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: shieldflow-0.1.0.tar.gz
  • Upload date:
  • Size: 40.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for shieldflow-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d03212a82e5316cf57f2d0bfe9d34dca6ba04a3ecc89f98da3439567b0c205eb
MD5 193d86c4d987b9c196fa0362a746fc9c
BLAKE2b-256 053e4281ac3f73b208fa057c7a5ce69c78a43b82593d11636054663b6b23e2d3

See more details on using hashes here.

File details

Details for the file shieldflow-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: shieldflow-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 34.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for shieldflow-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 534c1f06b17f66a75c8f64d94a8e22bd8c4841d4e118c7c4ef55519018481498
MD5 7ae9564f5f1bb096d3b43d98f65b03c9
BLAKE2b-256 c8e4125df011cf8073114ec55c117615eadaded1b46bd2c86ea1e894241d6efa

See more details on using hashes here.

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