Scanner Engine
The AgentCop scanner uses AST (Abstract Syntax Tree) analysis to find security issues in agent code before deployment.
How It Works
The scanner does not use regex-based string matching. It parses the full AST of your Python code and walks the tree, identifying security-relevant constructs: function calls, variable assignments, imports, and string formatting expressions.
The core technique is taint tracking — following data from sources (user input, HTTP requests, environment variables) through assignments and transformations to dangerous sinks (LLM calls, subprocess invocations, eval).
Source (user_input) → assignment → f-string → LLM prompt
↑
FLAGGED: LLM01 Prompt Injection
Detection Categories
The scanner maps each detection to the relevant OWASP LLM Top 10 category.
| Category | OWASP | What it detects |
|---|---|---|
| Prompt Injection | LLM01 | f-strings, .format(), concatenation in prompts |
| Insecure Output | LLM02 | eval(), exec(), compile() on LLM output |
| Sensitive Data | LLM06 | Hardcoded API keys, passwords, tokens |
| Excessive Agency | LLM08 | Shell tools, file write, email without gates |
| DoS Patterns | LLM04 | Infinite loops, unbounded recursion |
| Training Poisoning | LLM03 | Unvalidated writes to vector stores |
Trust Score Calculation
Each scan produces a Trust Score from 0 to 100. The score degrades based on the severity of detected issues.
- Starts at 100
- CRITICAL issues: −25 each (floor at 0)
- HIGH issues: −15 each
- MEDIUM issues: −8 each
- LOW issues: −3 each
Code Examples — What the Scanner Finds
# These patterns trigger Scanner Engine detections:
# LLM01: Prompt Injection — f-string with external data
def vulnerable_prompt(user_input):
prompt = f"Answer this: {user_input}" # FLAGGED
return llm.invoke(prompt)
# LLM02: Insecure Output — eval() on agent result
result = agent.run(task)
eval(result) # FLAGGED
# LLM06: Sensitive Data — hardcoded secret
api_key = "sk-ant-api03-abc123" # FLAGGED
# Safe patterns — these do NOT trigger:
def safe_prompt(user_input):
template = PromptTemplate(template="Answer: {question}", input_variables=["question"])
return llm.invoke(template.format(question=user_input)) # Safe
Scan via API
import httpx
result = httpx.post("https://api.agentcop.live/api/scan", json={
"code": open("agent.py").read(),
"description": "Customer support agent"
}).json()
for issue in result["issues"]:
print(f"[{issue['severity']}] {issue['type']}: {issue['description']}")
if issue.get("line"):
print(f" Line {issue['line']}: {issue.get('code_snippet', '')}")
the scanner is necessary but not sufficient. a clean scan score means your code has no known static patterns — not that your agent is safe at runtime.