Zero-Trust Middleware for Agentic Coding
Project description
๐ก๏ธ AgentArmor
Zero-Trust Security Middleware for AI-Generated Code
The layer between your AI coding tool and your production codebase.
๐ฆ Install ยท ๐ Quickstart ยท ๐ Docs ยท ๐๏ธ Examples ยท ๐ค Contribute
โ ๏ธ The Problem Nobody Is Talking About
In 2026, developers ship millions of lines of AI-generated code every day. Cursor, Claude Code, GitHub Copilot, Windsurf โ these tools are phenomenally productive.
But they have a dirty secret:
# โ
This is what your AI agent confidently wrote for you
def get_user_profile(user_id):
api_key = "sk-live_a8f3c2b1d4e5f6a7b8c9" # ๐ด SECRET IN SOURCE CODE
query = f"SELECT * FROM users WHERE id={user_id}" # ๐ด SQL INJECTION
user_code = request.args.get("transform")
result = eval(user_code) # ๐ด REMOTE CODE EXECUTION
img_url = request.json.get("avatar")
img = requests.get(img_url).content # ๐ด SERVER-SIDE REQUEST FORGERY
pw_hash = hashlib.md5(password.encode()).hexdigest() # ๐ด BROKEN CRYPTOGRAPHY
return db.execute(query).fetchone()
This is not hypothetical. Every one of these patterns has been documented in production AI-generated code in 2025โ2026. The code looks correct. It passes basic review. It ships.
AgentArmor catches all 5 vulnerabilities above โ in under 10 milliseconds.
๐ By The Numbers
| Stat | Value |
|---|---|
| ๐ฏ Threat categories detected | 19 |
| ๐ OWASP Top 10 categories covered | 9 / 10 |
| ๐งช Tests passing | 195 / 195 |
| โก Avg. scan time | < 10ms |
| ๐ฆ Python versions supported | 3.9 โ 3.13 |
| ๐๏ธ Vulnerability museum cases | 10 |
| ๐ง Zero external API calls | โ 100% local |
๐ 30-Second Quickstart
pip install kvlr
from agent_armor import AgentArmor
armor = AgentArmor()
# Paste any AI-generated code here
ai_code = '''
import hashlib, requests
api_key = "sk-live_a8f3c2b1d4e5"
query = f"SELECT * FROM users WHERE id={user_id}"
requests.get(user_supplied_url)
hashlib.md5(password).hexdigest()
'''
report = armor.process(ai_code, filename="generated.py")
print(f"Status: {report.status}") # โ BLOCKED
print(f"Threats: {len(report.ast_findings)} found") # โ 3 found
๐ก๏ธ [AgentArmor] Intercepting AI-generated code...
๐ [Stage 1] Secret detected: sk-live_a8f3c2b1d4e5 โ replaced with os.getenv()
๐ฒ [Stage 2] CRITICAL: SQL injection via f-string at line 3
๐ฒ [Stage 2] HIGH: SSRF โ non-literal URL at line 4
๐ฒ [Stage 2] HIGH: InsecureCryptography โ hashlib.md5() at line 5
๐ [Stage 5] 2 policy violations
๐ Status: BLOCKED | 3 AST findings | 1 secret scrubbed | 2 policy violations
Or via the CLI:
kvlr scan my_ai_generated_file.py
kvlr scan my_ai_generated_file.py --report --output report.json
kvlr check-deps requirements.txt # slopsquatting / dependency confusion
๐ค Why AgentArmor? Why Now?
| The Old World | The AI-Agent World |
|---|---|
| Humans write code, humans review it | AI writes entire features unattended |
| Vulnerabilities are rare mistakes | Vulnerabilities are statistically guaranteed |
| SAST tools scan your code | AI code has no ownership, no blame, no accountability |
| Secrets accidentally committed | Secrets confidently hardcoded by agents with no env context |
| One dev, one file at a time | One prompt, 500 lines of code, shipped in 30 seconds |
Traditional SAST tools were not built for this. They assume a human wrote the code and will read the warning. AgentArmor is built as middleware โ it sits in the pipeline before the code ever reaches a human or a git commit.
Works with every AI coding tool
| Tool | How to integrate |
|---|---|
| Cursor / Windsurf | Run armor scan in a pre-commit hook |
| Claude Code | Wrap your agent's output through AgentArmor().process() |
| GitHub Copilot | CI/CD gate via the GitHub Actions workflow (included) |
| LangChain / CrewAI agents | Use as middleware in your agent pipeline |
| MCP servers | Drop-in armor mcp-proxy --port 8080 |
| Any LLM | Python API โ 3 lines of code |
๐ What AgentArmor Catches
Severity: ๐จ CRITICAL
These will get you breached. AgentArmor blocks code with these patterns:
| Pattern | Example | Why It's Dangerous |
|---|---|---|
| SQL Injection | f"SELECT * WHERE id={uid}" |
Full database dump / destruction |
| Code Execution | eval(user_input) |
Remote code execution on your server |
| Unsanitized data โ dangerous sink | input() โ subprocess.run() |
RCE via crafted user input |
Severity: ๐ด HIGH
These will get you breached eventually. AgentArmor warns with remediation:
| Pattern | Example | OWASP |
|---|---|---|
| SSRF | requests.get(user_url) |
A10 |
| Command Injection | os.system(f"ping {host}") |
A03 |
| Insecure Crypto | hashlib.md5(password) |
A02 |
| Secrets in code | api_key = "sk-live_..." |
A02 |
| YAML RCE | yaml.load(data) no Loader |
A08 |
| Pickle RCE | pickle.loads(data) |
A08 |
| JWT Algorithm None | jwt.decode(tok, algs=[]) |
A02 |
| BOLA/IDOR | WHERE id=? no user scope |
A01 |
| Admin route no auth | @app.route("/admin") bare |
A07 |
| Dependency confusion | pip install internal-tool |
A08 |
Severity: ๐ก MEDIUM / ๐ต LOW
Best-practice enforcement: missing error handling, bare except:, assert for
security checks, hardcoded debug flags, private IPs in config.
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your AI Coding Tool โ
โ (Cursor ยท Claude Code ยท Copilot ยท LangChain) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AI-generated code (raw)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โก AgentArmor Pipeline โ
โ โ
โ Stage 1 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๐ Secret Scrubber โ โ
โ โ Regex + Shannon entropy โ 13 secret types โ โ
โ โ Replaces with os.getenv() calls automatically โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Stage 2 โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๐ฒ AST Hardening Engine โ โ
โ โ True structural analysis โ not just grep โ โ
โ โ Detects 12 threat patterns at the syntax tree โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Stage 3 โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๐ DTG Engine (Data Transformation Graph) โ โ
โ โ Traces tainted data: sources โ sanitisers โ sinks โ โ
โ โ Auto-injects Pydantic validation schemas โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Stage 4 โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๐ฆ Slopsquatting Guard โ โ
โ โ Real-time PyPI/npm registry validation โ โ
โ โ Typosquatting detection via edit distance โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Stage 5 โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๐ Semantic Policy Engine (10 built-in rules) โ โ
โ โ BOLA ยท debug=True ยท no-auth admin ยท JWT alg โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Stage 6 โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๐ Shadow-Chain Attestation โ โ
โ โ SHA-256 signs security invariants in code โ โ
โ โ Detects if a human/AI later removes auth checks โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โผ โผ โผ
โ
APPROVED โ ๏ธ WARNED ๐ BLOCKED
(attested + signed) (report only) (pipeline halted)
โจ Feature Overview
|
๐ Secret Scrubber
๐ฒ AST Hardening Engine
๐ DTG Engine
|
๐ Shadow-Chain Attestation (novel)
๐ฆ Slopsquatting Guard
๐ฆ MCP Security Proxy
๐ Semantic Policy Engine
|
๐ Policy Engine Rules
| Rule | ID | Severity | Detects |
|---|---|---|---|
| Sensitive Path Write | RULE-001 | CRITICAL | open('/etc/passwd', 'w') |
| Delete Without User ID | RULE-002 | CRITICAL | DELETE ops without ownership scope |
| Domain Isolation | RULE-003 | HIGH | Frontend code reading backend env vars |
| Admin Endpoint Auth | RULE-004 | HIGH | /admin routes missing auth decorator |
| JWT Algorithm Required | RULE-005 | HIGH | jwt.decode() without algorithms= |
| Insecure Cryptography | RULE-007 | HIGH | hashlib.md5/sha1, PyCryptodome DES/ARC4 |
| SSRF | RULE-008 | HIGH | HTTP calls with dynamic (user-controlled) URLs |
| Broken Object-Level Auth | RULE-009 | HIGH | WHERE id = ? without ownership column |
| Insecure Design | RULE-010 | CRITICAL | debug=True, hardcoded secrets, private IPs |
๐ฆ Installation
# Option 1: PyPI (recommended)
pip install kvlr
# Option 2: Latest from source
git clone https://github.com/TanmayD03/Agent-Armor.git
cd kvlr
pip install -e .
Verify:
armor --version
# AgentArmor 1.0.0
๐ง Usage
CLI
# Scan a Python file for vulnerabilities
kvlr scan suspicious_code.py
# Scan with detailed JSON report
kvlr scan suspicious_code.py --report --output report.json
# Verify attestation integrity (CI/CD use)
armor verify suspicious_code.py --hash a3f9b2c1...
# Validate dependencies against PyPI/npm
kvlr check-deps requirements.txt
# Run the Vulnerability Museum demo
armor museum
# Start the MCP Security Proxy server
armor mcp-proxy --port 8080
# Show shadow-chain history for a file
armor history suspicious_code.py
Python API
from agent_armor import AgentArmor
from agent_armor.core.ast_hardener import ASTHardener
from agent_armor.core.policy_engine import PolicyEngine
# โโ Full pipeline โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
armor = AgentArmor()
ai_code = '''
import hashlib, requests, yaml
from flask import Flask, request, jsonify
app = Flask(__name__)
app.secret_key = "hardcoded-secret" # RULE-010
@app.route("/profile/<int:uid>")
def get_profile(uid):
cfg = yaml.load(request.json["cfg"]) # yaml RCE
url = request.json["avatar"]
img = requests.get(url).content # SSRF
pw = hashlib.md5(b"pass").hexdigest() # weak hash
row = db.execute(
"SELECT * FROM users WHERE id = ?",
(uid,) # BOLA
).fetchone()
return jsonify(dict(row))
if __name__ == "__main__":
app.run(debug=True) # RULE-010
'''
report = armor.process(ai_code, filename="profile.py")
print(f"Status: {report.status}") # BLOCKED
print(f"AST: {len(report.ast_findings)} findings")
print(f"Policy: {len(report.policy_violations)} violations")
print(f"Secrets: {len(report.secret_findings)} secrets scrubbed")
# โโ Individual engines โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# AST Hardener โ structural analysis
h = ASTHardener()
for f in h.analyze("import hashlib\nh = hashlib.md5(data)\n"):
print(f" [{f.severity}] {f.node_type}: {f.description}")
# โ [HIGH] InsecureCryptography: hashlib.md5() uses a broken algorithm...
# Policy Engine โ semantic rules
p = PolicyEngine()
for v in p.evaluate('app.run(debug=True)\n', "app.py"):
print(f" [{v.severity}] {v.rule_id}: {v.description}")
# โ [CRITICAL] RULE-010-INSECURE-DESIGN: debug=True enables the interactive debugger...
Expected Output
๐ก๏ธ [AgentArmor] Intercepting AI-generated code...
๐ [Stage 1/5] Scanning for hardcoded secrets...
โ ๏ธ Found 1 secret(s). Replacing with env var references.
๐ฒ [Stage 2/5] Running AST security analysis...
๐จ CRITICAL [line 6]: SQL injection via f-string in .execute()
๐จ CRITICAL [line 8]: Dangerous sink โ eval()
๐ [Stage 3/5] Analyzing data transformation graph...
โ ๏ธ Unsanitized flow: request.args โ eval() [CRITICAL]
๐ฆ [Stage 4/5] Validating package dependencies...
๐ [Stage 5/5] Enforcing security policies...
๐ [AgentArmor] Code BLOCKED by Zero-Trust policy.
Status: BLOCKED
Critical issues: 3
Attestation: BLOCKED
๐ Detection Coverage
AgentArmor covers all OWASP Top 10 2021 categories relevant to AI-generated code:
| Detection | Engine | Severity | OWASP Category |
|---|---|---|---|
SQL Injection (f-string / % in .execute()) |
AST | CRITICAL | A03 Injection |
| eval() / exec() / __import__() | AST | CRITICAL | A03 Injection |
| os.system() / subprocess shell=True | AST | HIGH | A03 Injection |
| pickle.loads() / marshal.loads() | AST | HIGH | A08 Software Integrity |
| yaml.load() without Loader= | AST | HIGH | A08 Software Integrity |
| hashlib.md5 / sha1 / new("md5") | AST + Policy | HIGH | A02 Crypto Failures |
| requests.get(user_url) โ SSRF | AST + Policy | HIGH | A10 SSRF |
| re.compile(r"(a+)+") โ ReDoS | AST | HIGH | A06 Vulnerable Components |
| Hardcoded secrets / API keys / tokens | Secret Scrubber | HIGH | A02 Crypto Failures |
| assert for security checks | AST | MEDIUM | A07 Auth Failures |
| Missing try/except on I/O | AST | MEDIUM | A09 Logging Failures |
| Sensitive path writes (/etc, ~/.ssh) | Policy RULE-001 | HIGH | A01 Broken Access |
| Delete without user_id scope | Policy RULE-002 | HIGH | A01 Broken Access |
| Admin routes missing auth | Policy RULE-004 | HIGH | A07 Auth Failures |
| jwt.decode() without algorithms= | Policy RULE-005 | HIGH | A02 Crypto Failures |
| WHERE id=? without ownership column (BOLA/IDOR) | Policy RULE-009 | HIGH | A01 Broken Access |
| debug=True / hardcoded secret_key / private IP | Policy RULE-010 | CRITICAL | A05 Misconfig |
| Typosquatting / sloppy package names | Slopsquatting | HIGH | A08 Software Integrity |
| Unsanitized input โ dangerous sink (DTG) | DTG Engine | CRITICAL | A03 Injection |
โก Interactive Examples
python examples/quickstart.py # all 10 categories
python examples/quickstart.py --section crypto # insecure cryptography
python examples/quickstart.py --section ssrf # SSRF detection
python examples/quickstart.py --section redos # catastrophic ReDoS
python examples/quickstart.py --section pipeline # kitchen-sink demo
Each section shows: vulnerable code โ live detection output โ hardened fix.
๐๏ธ Vulnerability Museum
The vulnerability_museum/ folder contains real examples of AI-generated vulnerable
code and how AgentArmor fixes each one:
| # | Vulnerability | OWASP 2021 | CVSS | AgentArmor Fix |
|---|---|---|---|---|
| 01 | SQL Injection | A03 Injection | 9.8 | Parameterised queries auto-injected |
| 02 | eval() Code Injection | A03 Injection | 10.0 | Code blocked + refactor guide |
| 03 | Secret Key Exposure | A02 Crypto Failures | 9.1 | Env var replacement |
| 04 | OS Command Injection | A03 Injection | 9.8 | subprocess list-form hardening |
| 05 | Dependency Confusion | A08 Software Integrity | 8.1 | Slopsquatting guard blocks install |
| 06 | Missing Auth on Admin Route | A07 Auth Failures | 9.1 | Auth decorator enforcement |
| 07 | JWT Algorithm None | A02 Crypto Failures | 8.8 | algorithms= parameter required |
| 08 | Delete Without User ID | A01 Broken Access | 8.1 | Ownership scope enforced |
| 09 | Insecure Cryptography | A02 Crypto Failures | 7.5 | scrypt / SHA-256 replacement |
| 10 | SSRF | A10 SSRF | 8.6 | Allowlist URL validation |
# Run the museum demo
armor museum
๐ฌ Research Foundation
AgentArmor is grounded in published 2025โ2026 security research โ not just intuition:
| Concept | Source | AgentArmor Implementation |
|---|---|---|
| Semantic Over-Confidence Mitigation | LLM Security Survey, 2025 | AST-level missing error handling detection |
| Formal Invariant Verification | Mitsubishi Rapid Formal Verification, 2025 | RULE-002: delete ops require user_id guard |
| Data Transformation Graph (DTG) Analysis | DTG Security, 2026 | Tainted data sourceโsanitiserโsink tracing |
| Shadow-Chain Attestation | Novel โ AgentArmor (2026) | SHA-256 invariant signing on every scan |
| Slopsquatting / AI Dependency Confusion | AI Supply Chain Research, 2025 | Real-time registry + entropy validation |
| BOLA/IDOR in AI code | OWASP API Security 2023 | RULE-009: ownership column enforcement |
๐๏ธ The "Secure-by-Agent" Badge
Add this to your README to show your codebase is AgentArmor-protected:
[](https://github.com/yourusername/kvlr)
๐ค Author
Tanmay Dikey
๐๏ธ Add the Badge to Your Project
Show the world your codebase is AgentArmor-protected:
[](https://github.com/TanmayD03/Agent-Armor)
๐ค Contributing
Contributions are welcome! The most impactful things you can add:
- ๐ New detection rules โ found a pattern that AI generates dangerously? Open a PR
- ๐๏ธ Vulnerability museum cases โ real AI-generated vulnerable code examples
- ๐ Language support โ AgentArmor currently covers Python; JS/TS is next
- ๐ Documentation โ examples, blog posts, case studies
See CONTRIBUTING.md for the full guide, including how to add a new detection rule in under 30 lines of code.
๐ค Author
Tanmay Dikey โ Security researcher & the mind behind AgentArmor
๐ License
MIT License โ Copyright (c) 2026 Tanmay Dikey โ see LICENSE for details.
If AgentArmor has saved you from a vulnerability, please โญ star the repo.
It's the best way to help other developers find this tool before their AI agent ships something dangerous.
"The question is no longer whether AI will write your code. The question is whether anyone is checking its work."
โ Tanmay Dikey, 2026
Project details
Release history Release notifications | RSS feed
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 kvlr-1.0.0.tar.gz.
File metadata
- Download URL: kvlr-1.0.0.tar.gz
- Upload date:
- Size: 72.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c6cf3f8465198f2a970481c677d0f2b171682d96212091a357b8133a5e44ca8
|
|
| MD5 |
b3513d3812a7d4c90ca0859f3d65a948
|
|
| BLAKE2b-256 |
41153f94f290196569a0d375d4138a5c056968625e781d67eddf4cfed413514e
|
Provenance
The following attestation bundles were made for kvlr-1.0.0.tar.gz:
Publisher:
ci.yml on TanmayD03/Agent-Armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kvlr-1.0.0.tar.gz -
Subject digest:
6c6cf3f8465198f2a970481c677d0f2b171682d96212091a357b8133a5e44ca8 - Sigstore transparency entry: 1006177774
- Sigstore integration time:
-
Permalink:
TanmayD03/Agent-Armor@c81740faae74313393321074b67bfbb53e33d93f -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/TanmayD03
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c81740faae74313393321074b67bfbb53e33d93f -
Trigger Event:
push
-
Statement type:
File details
Details for the file kvlr-1.0.0-py3-none-any.whl.
File metadata
- Download URL: kvlr-1.0.0-py3-none-any.whl
- Upload date:
- Size: 61.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e449be94530bef9192fe244c31b4759cdad9904fb0968376041a906866d98e2
|
|
| MD5 |
b425e9481a589fd0bb50544f1d4bc274
|
|
| BLAKE2b-256 |
83efc11700a29c5cdde2362232f6752f9db248cb33094bef82b1efaec40854e0
|
Provenance
The following attestation bundles were made for kvlr-1.0.0-py3-none-any.whl:
Publisher:
ci.yml on TanmayD03/Agent-Armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kvlr-1.0.0-py3-none-any.whl -
Subject digest:
9e449be94530bef9192fe244c31b4759cdad9904fb0968376041a906866d98e2 - Sigstore transparency entry: 1006177781
- Sigstore integration time:
-
Permalink:
TanmayD03/Agent-Armor@c81740faae74313393321074b67bfbb53e33d93f -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/TanmayD03
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c81740faae74313393321074b67bfbb53e33d93f -
Trigger Event:
push
-
Statement type: