langchain-security-extension

LangChain Security Extension Documentation

Python Versions License Zero-Dependency Core LangChain Compatible

Deterministic, Zero-Trust Policy Enforcement Points (PEPs) for LangChain Agents
Shift your enterprise AI from fragile, prompt-dependent guardrails to deterministic, code-level governance.


🗺️ Documentation Portal

This documentation portal provides architectural blueprints, step-by-step rollout guides, and module specifications for securing enterprise LLM applications.

Documentation Resource Description Destination
🚀 Quickstart Demo (“Seeing is Believing”) Hands-on walkthrough to clone the demonstrator, run unhardened (main) vs hardened (secured) test suites, and explore the complete 46-test catalog. Open Quickstart Walkthrough
📘 Enterprise Implementation Guide 12-chapter comprehensive walkthrough using a real-world enterprise incident assistant to demonstrate hardening from scratch. Open Implementation Guide
⚙️ Unified Configuration Reference Complete index of all configuration properties, environment variable overrides, defaults, and operational behaviors. Browse Configuration Reference
📚 API Reference Complete module specifications for security_core, security_adapter_langchain, and security_pdp_opa. Browse API Reference
🧪 Companion Reference Application Working FastAPI + LangChain demonstrator application illustrating baseline vulnerabilities (main) vs hardened controls (secured). View on GitHub
💻 Source Code Repository Core library repository, Installation instructions, issue tracker, and contribution guidelines. GitHub Repository

⚡ Quickstart

Protect tool calls with Common Expression Language (CEL) argument constraints, caller role checks, and numeric clearance levels. Identity context propagates deterministically in-band via LangChain’s native RunnableConfig without prompt overhead:

from langchain_security_extension.security_adapter_langchain import secured_tool
from langchain_security_extension.security_core import IdentityBridge, SecurityIdentity, ToolExecutionDeniedError


# 1. Protect any tool with deterministic CEL argument constraints
@secured_tool(
    required_roles=["DEVOPS"],
    min_clearance=1,
    cel_expression="args.server.startsWith('prod-') ? subject.dept == 'INFRA' : true",
    is_mutative=True
)
def example_tool_op_reboot_server(server: str) -> str:
    return f"Rebooted {server}"


# Helper: attach identity to LangChain RunnableConfig
def caller(dept: str):
    return IdentityBridge.create_runnable_config(
        SecurityIdentity.create("alice", "CORP", {"DEVOPS"}, 1, dept)
    )


# 2. Authorized caller (DEVOPS + INFRA) -> PERMIT
print(example_tool_op_reboot_server("prod-db-01", config=caller("INFRA")))
# Output: "Rebooted prod-db-01"

# 3. Unauthorized caller (DEVOPS + MARKETING) -> Hard-aborted with 0 LLM tokens!
# example_tool_op_reboot_server("prod-db-01", config=caller("MARKETING"))
# Raises: ToolExecutionDeniedError (PARAMETER_CONSTRAINT_FAILED)

🛑 The Problem: Why Prompt Guardrails Are Not Security

Vulnerability Vector Prompt-Based Guardrails (e.g. Llama Guard, NeMo) langchain-security-extension (Code-Level PEPs)
Determinism ❌ Stochastic (bypassed via jailbreaks & indirect prompt injection) ✅ 100% Deterministic (enforced in Python bytecode before tool invocation)
Token Cost ❌ Adds 200–1,500 tokens per turn + recursive retry token burn ✅ 0 LLM Tokens (front-door denial + invocation retry budgets)
Context Forgery ❌ Security parameters exposed in tool JSON schemas can be hallucinated ✅ Schema Hiding strips security attributes before model binding
Argument Validation ❌ Cannot reliably validate dynamic args (e.g. CIDR blocks, hostnames) ✅ CEL Expressions evaluate tool arguments against live subject attributes
Data Retrieval (RAG) ❌ Post-retrieval filtering causes cross-tenant leaks or result starvation ✅ Native DB Pre-Filters + signed sec:* chunk envelopes & oversampling
Data Privacy (DLP) ❌ Scattered manual regex hooks prone to developer oversight ✅ Single-Point DLP masks PII, secrets, and payment cards in-flight
Compliance & SIEM ❌ Synchronous or unstructured logs that stall agents or fail audits ✅ Async Ring Buffer streaming OCSF, ECS, and RFC 5424 audit events

🏗️ Architecture & Enforcement Lifecycle

The framework implements a distributed Zero-Trust Policy Enforcement Architecture aligned with NIST SP 800-207. The core policy decision engine is strictly separated from the LangChain orchestration layer, ensuring security evaluation executes independently of model prompts.

Modular Layered Architecture

flowchart TB
    subgraph HostApp["Host Application Layer (Any LangChain App)"]
        Agent["LangChain Agent / LCEL Chain"]
        Tool["Python Tool Callables"]
        Retriever["Vector Store / Retriever"]
    end

    subgraph Adapters["security_adapter_langchain (PEP Integration Layer)"]
        SR["SecureRunnable\n(Agent/Chain PEP)"]
        ST["@secured_tool\n(Tool Interceptor PEP)"]
        SRET["SecureRetriever\n(RAG Context Pre-Filter PEP)"]
        IB["IdentityBridge\n(RunnableConfig Context Injector)"]
    end

    subgraph Core["security_core (Zero-Dependency Engine)"]
        PDP["Policy Decision Engine (PDP)\n- Two-Tier Decision Cache (L1 Thread-Local / L2 TTL)\n- RoleGraph & Clearance Hierarchy"]
        CEL["CEL Evaluator\n- Runtime Argument Validation\n- Attribute-Based Access Control (ABAC)"]
        Audit["Audit Pipeline & PII Sanitizer\n- OCSF / ECS / RFC 5424 Emitter\n- In-Flight DLP & Parameter Redaction"]
    end

    subgraph External["Pluggable Backends & SPIs"]
        OPA["Remote PDP (OPA / Cedar)"]
        SIEM["SIEM (Splunk / Elastic / Datadog)"]
        VDB["Vector DBs (Chroma / Pinecone / pgvector)"]
    end

    Agent <--> SR
    Tool <--> ST
    Retriever <--> SRET
    IB -.->|"Injects SecurityIdentity"| Agent

    SR & ST & SRET -->|"PolicyRequest"| PDP
    ST -->|"Evaluate args"| CEL
    SR & ST & SRET -->|"AuditEvent"| Audit

    PDP -.->|"Optional SPI"| OPA
    Audit -.->|"AuditPublisherSPI"| SIEM
    SRET -.->|"Metadata Pre-filters"| VDB

NIST SP 800-207 Zero-Trust PEP / PDP Mapping

Zero-Trust Role Library Component Implementation Responsibilities
PEP
(Policy Enforcement Point)
@secured_tool
SecureRunnable
SecureRetriever
• Intercepts execution requests before tool/chain execution.
• Enforces caller role and clearance floors.
• Applies vector DB metadata pre-filters and prunes documents.
• Emits immutable structured audit events to SIEM.
PDP
(Policy Decision Point)
EmbeddedPolicyEngine
RemotePDPAdapter
• Evaluates authorization requests deterministically.
• Manages two-tier decision caching (L1 thread-local, L2 LRU TTL).
• Resolves hierarchical role graphs and multi-tenant isolation.
• Evaluates fail-closed / fail-open circuit breakers on remote PDP outages.
PIP
(Policy Information Point)
IdentityBridge
EntityAttributeResolverSPI
• Converts inbound JWT/OAuth claims into immutable SecurityIdentity.
• Injects identity into LangChain’s native RunnableConfig.
• Resolves dynamic entity attributes (e.g. server owner, user dept) for CEL rules.
PAP
(Policy Administration Point)
Declarative Decorators & CEL Expressions • Declarative @secured_tool parameters (required_roles, min_clearance).
• Common Expression Language rules evaluated over live arguments.
• Metadata classification schemas (sec.clearance, sec.department).

PEP Interception Lifecycle

sequenceDiagram
    autonumber
    actor Caller as Caller / Application
    participant Bridge as IdentityBridge
    participant Runnable as SecureRunnable (Agent PEP)
    participant ToolPEP as @secured_tool (Tool PEP)
    participant PDP as EmbeddedPolicyEngine (PDP)
    participant CEL as CELEvaluator
    participant SIEM as AuditPublisherSPI
    participant Tool as Target Tool Function

    Caller->>Bridge: create_runnable_config(identity)
    Bridge-->>Caller: config: RunnableConfig
    Caller->>Runnable: invoke(input, config)
    
    Runnable->>PDP: evaluate(subject, action="AGENT_INVOKE")
    PDP-->>Runnable: PERMIT
    
    Runnable->>ToolPEP: invoke_tool(args, config)
    
    rect rgb(240, 248, 255)
        Note over ToolPEP,CEL: Pre-Execution Code PEP (0 LLM Tokens)
        ToolPEP->>CEL: evaluate_expression(cel_rule, args, subject)
        CEL-->>ToolPEP: Condition Satisfied
        ToolPEP->>PDP: evaluate(subject, action="TOOL_EXECUTE", resource)
        PDP-->>ToolPEP: PERMIT (cached / local)
        ToolPEP->>SIEM: publish(AuditEvent: PERMIT)
    end
    
    ToolPEP->>Tool: execute(*args, **kwargs)
    Tool-->>ToolPEP: raw_result
    ToolPEP-->>Runnable: sanitized_result
    Runnable-->>Caller: execution_output

📖 Implementation Guide Overview

The Enterprise Implementation Guide covers end-to-end integration across a hands-on quickstart, 12 focused architectural chapters, and a unified configuration reference:

  1. Quickstart Walkthrough: “Seeing is Believing” Hands-On Demo
  2. Architecture Blueprint & System Boundaries
  3. Connecting Your Identity Provider
  4. Setting Up Your Authorization Engine
  5. Protecting Agents and Execution Entry Points
  6. Security Labeling and Admission Control in the Ingestion Pipeline
  7. Integrating Your Vector Database
  8. Guarding Tools and Enterprise APIs
  9. Defending Against Agent Looping
  10. Sanitizing Sensitive Payloads
  11. Connecting to Enterprise SIEM and Log Aggregators
  12. Enforcing Multi-Tenancy
  13. Troubleshooting & Diagnostics
  14. Unified Configuration Reference