Security Scanning
Every agent plugin on PIE undergoes automated security analysis. This page explains how the system works, what it checks, and how to ensure your plugin passes.
How It Works
When you create, update, or import a plugin, PIE automatically runs a security scan using an AI-powered code analysis system (Claude Opus 4.6 via OpenRouter). The scan evaluates your plugin code and manifest against a set of security criteria.
Each scan produces:
- Pass/Fail result for each of the 10 security criteria
- An overall pass/fail status (all criteria must pass for an overall pass)
- A summary with a brief explanation of the findings
When Scans Run
Scans are triggered automatically in these situations:
| Trigger | When |
|---|---|
| Plugin created | When a new plugin with code or a prompt template is created |
| Plugin updated | When code, prompt template, or manifest changes |
| Plugin imported | When a .pie file is imported via the Developer Portal |
| Manual trigger | When a developer clicks "Run Scan" in the Security tab |
Auto-triggered scans use code hashing (SHA-256) to avoid redundant scans -- if the code hasn't changed since the last scan, the scan is skipped.
Security Criteria
Your plugin is evaluated against these 10 criteria:
1. No Data Exfiltration
Code must not send user data, conversation content, or secrets to unauthorized external endpoints. Your plugin should only communicate with APIs relevant to its stated purpose.
2. No Credential Harvesting
Code must not capture, log, or exfiltrate API keys, tokens, passwords, or secrets. Using context.secrets for your plugin's own API keys is perfectly fine.
3. No Filesystem Abuse
Code must not attempt to access, read, or write files outside its sandbox scope. Path traversal patterns and attempts to access system files will be flagged.
4. No Code Injection
Code must not use eval(), new Function(), or other dynamic code execution with untrusted input. Safe uses of JSON.parse() are acceptable.
5. No Network Abuse
Code must only make requests to hosts related to its stated purpose. A GitHub plugin calling the GitHub API is fine; a weather plugin calling an unknown endpoint is not.
6. No Crypto Mining / Resource Abuse
Code must not contain cryptocurrency mining, intentional infinite loops, or deliberate resource exhaustion patterns.
7. No Obfuscated Code
Code must be readable and not contain meaningfully obfuscated or encoded payloads designed to hide behavior. Base64-encoded config strings with clear purpose are acceptable.
8. No Privacy Violations
Code must not collect, store, or transmit PII beyond what is necessary for its stated function.
9. No Privilege Escalation
Code must not attempt to break out of its sandbox, access the host process, or escalate permissions.
10. Safe Dependencies
Any referenced external URLs or APIs must be legitimate, well-known services matching the plugin's stated purpose.
Viewing Results
Marketplace & Plugin Pages
Every plugin displays a security badge:
- Verified (green) -- All criteria passed
- Security Issues (red) -- One or more criteria failed
- Scanning... (yellow) -- Scan in progress
- Not Scanned (gray) -- No scan has been run yet
On the plugin detail page, you can expand the full security report to see individual criteria results with explanations.
Developer Portal
In the Developer Portal, the Security tab shows:
- Current scan status and summary
- Detailed breakdown of all 10 criteria with pass/fail indicators
- Scan history showing previous scan results
- A Run Scan button to manually trigger a new scan
Tips for Passing
- Only call APIs relevant to your plugin's purpose -- If your plugin is a weather tool, only call weather APIs
- Use
context.secretsfor credentials -- Never hardcode API keys or tokens - Use
context.oauth.fetch()for authenticated requests -- This is the approved way to make OAuth-authenticated calls - Write readable code -- Avoid unnecessary string encoding or variable name obfuscation
- Declare network access in your manifest -- List the hosts your plugin needs to access
- Don't use
eval()ornew Function()-- Use standard JavaScript patterns instead
API Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /api/plugins/:id/security | No | Get latest scan result |
POST | /api/plugins/:id/security/scan | Yes (author) | Manually trigger a scan |
GET | /api/plugins/:id/security/history | Yes (author) | Get scan history |