This guide explains the automated security scanning procedures used in the Synaptic Canvas marketplace. Security scanning helps identify potential vulnerabilities, coding issues, and policy violations before they reach users.
Automated security scanning serves several critical functions:
- Early Detection: Identify security issues during development
- Consistent Standards: Apply uniform security checks across all packages
- Risk Reduction: Prevent vulnerable code from reaching users
- Compliance: Ensure packages meet marketplace security requirements
- Transparency: Provide visibility into security practices
The security scanner is implemented in scripts/security-scan.py and performs six categories of checks:
- Secrets Detection
- Script Quality
- Python Safety
- Package Documentation
- License Files
- Dependency Audit
# Full security scan
./scripts/security-scan.py
# Quick scan (skip slow checks)
./scripts/security-scan.py --quick
# JSON output for CI/CD
./scripts/security-scan.py --json
# Scan single package
./scripts/security-scan.py --package sc-delay-tasksPurpose: Identify hardcoded credentials, API keys, and other sensitive data
What It Checks:
- Hardcoded passwords (
password = "...") - API keys (
api_key = "...") - Secret tokens (
secret = "...",token = "...") - AWS credentials (
AWS_KEY,AWS_SECRET) - GitHub tokens (
GITHUB_TOKEN) - Private keys (
private_key,BEGIN PRIVATE KEY) - Credentials in markdown documentation
Why It Matters:
Hardcoded secrets are a critical security vulnerability. If committed to a repository:
- Credentials are visible to anyone with access
- They remain in git history even if deleted
- Automated scanners can find and exploit them
- Rotating compromised credentials is difficult and expensive
Common Violations:
# BAD: Hardcoded API key
api_key = "sk_live_abc123xyz789"
# BAD: Password in configuration
db_password = "MySecretPassword123"
# GOOD: Use environment variables
api_key = os.environ.get('API_KEY')
db_password = os.environ['DB_PASSWORD']# BAD: Token in script
GITHUB_TOKEN="ghp_abc123xyz789"
# GOOD: Read from secure source
GITHUB_TOKEN="${GITHUB_TOKEN:-$(security find-generic-password -s github-token -w)}"How to Fix:
- Never commit secrets: Use environment variables or secure vaults
- Use .gitignore: Exclude config files with secrets
- Rotate exposed credentials: If you accidentally commit a secret, rotate it immediately
- Use secret managers: AWS Secrets Manager, Azure Key Vault, etc.
False Positives:
The scanner may flag:
- Example code showing the pattern (not actual secrets)
- Test fixtures with dummy credentials
- Documentation explaining secret handling
To address false positives:
- Make examples obviously fake:
password = "YOUR_PASSWORD_HERE" - Add comments:
# Example only, not a real credential - Use clearly fake values:
api_key = "test_key_not_real"
Purpose: Ensure shell scripts follow best practices and are maintainable
What It Checks:
- Scripts are executable (
chmod +x) - Shellcheck validation (if available)
- Shebang line present (
#!/usr/bin/env bash) - Error handling enabled (
set -eorset -euo pipefail)
Why It Matters:
Quality shell scripts:
- Fail fast when errors occur (prevent cascading failures)
- Are portable across systems (proper shebang)
- Are discoverable and runnable (executable permission)
- Follow community best practices (shellcheck)
Shellcheck Integration:
If shellcheck is installed, the scanner runs it on all .sh files:
# Install shellcheck
brew install shellcheck # macOS
apt-get install shellcheck # UbuntuShellcheck catches common issues:
- Unquoted variables
- Incorrect conditionals
- Unsafe word splitting
- Command substitution issues
Best Practices:
#!/usr/bin/env bash
# Good: Portable shebang, strict error handling
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Quote variables to prevent word splitting
file_name="my file.txt"
cat "$file_name" # GOOD
cat $file_name # BAD - breaks with spaces
# Use [[ ]] for conditionals (bash)
if [[ -f "$file_name" ]]; then # GOOD
if [ -f $file_name ]; then # OK but less robust
# Handle errors explicitly
if ! command; then
echo "Command failed"
exit 1
fiCommon Issues:
# Missing shebang
# IMPACT: Script may run with wrong shell
# FIX: Add #!/usr/bin/env bash at top
# Not executable
# IMPACT: Must run as "bash script.sh" instead of "./script.sh"
# FIX: chmod +x script.sh
# No error handling
# IMPACT: Script continues after failures
# FIX: Add "set -e" or "set -euo pipefail"Purpose: Detect unsafe Python patterns that could lead to security vulnerabilities
What It Checks:
eval()calls - arbitrary code executionexec()calls - arbitrary code executionshell=Truein subprocess - shell injection riskpickle.loads()- arbitrary code execution via deserialization
Why It Matters:
These patterns can allow attackers to:
- Execute arbitrary code on your system
- Read/modify sensitive files
- Escalate privileges
- Create backdoors
Unsafe Patterns:
# 1. eval() - NEVER USE
user_input = "print('hello')"
eval(user_input) # DANGER: Could be "__import__('os').system('rm -rf /')"
# 2. exec() - NEVER USE
code = request.get('code')
exec(code) # DANGER: Arbitrary code execution
# 3. shell=True - AVOID
import subprocess
file = user_input
subprocess.call(f"cat {file}", shell=True) # DANGER: Shell injection
# 4. pickle.loads() - AVOID
import pickle
data = pickle.loads(untrusted_data) # DANGER: Can execute code during loadSafe Alternatives:
# Instead of eval() for math
from ast import literal_eval
result = literal_eval("1 + 2") # Safe: Only evaluates literals
# Instead of exec() for dynamic behavior
# Use: dispatch tables, getattr(), or plugin systems
handlers = {
'action1': handle_action1,
'action2': handle_action2
}
handlers[user_choice]() # Safe: Controlled options
# Instead of shell=True
import subprocess
# Use list arguments (no shell)
subprocess.run(['cat', file]) # Safe: No shell injection
# Instead of pickle
import json
data = json.loads(untrusted_json) # Safer: Data only, no codeWhen These Patterns Are Acceptable:
The scanner may flag legitimate uses in:
- Development/debug scripts (not production)
- Controlled environments with trusted input only
- Legacy code being refactored
If you must use these patterns:
- Document why it's necessary
- Validate and sanitize all input
- Run in isolated environment
- Add extra security layers (sandboxing, permissions)
- Plan migration to safer alternatives
Purpose: Ensure all packages have complete, accurate documentation
What It Checks:
README.mdexists in each package- README mentions security
LICENSEfile presentmanifest.yamlexists and is valid YAMLCHANGELOG.mdexists (recommended)
Why It Matters:
Complete documentation:
- Helps users understand package purpose and usage
- Provides security information and best practices
- Establishes legal terms (license)
- Tracks changes and versioning (changelog)
- Meets marketplace requirements
Required Files:
packages/
your-package/
README.md # REQUIRED: Package description, usage
LICENSE # REQUIRED: Legal terms
manifest.yaml # REQUIRED: Package metadata
CHANGELOG.md # RECOMMENDED: Version history
README.md Requirements:
Must include:
- Package name and brief description
- Installation instructions
- Usage examples
- Security mention (link to SECURITY.md or security section)
- License information
Example:
# my-package
Brief description of what it does.
## Installation
\`\`\`bash
python3 tools/sc-install.py install my-package
\`\`\`
## Usage
Examples here...
## Security
See [SECURITY.md](../../SECURITY.md) for security practices.
## License
MITmanifest.yaml Requirements:
Must be valid YAML with required fields:
name: my-package
version: 1.0.0
description: What it does
author: your-handle
tags: [relevant, tags]
artifacts:
commands:
- commands/my-command.md
skills:
- skills/my-skill/SKILL.mdCommon Issues:
Missing README.md
→ Create README with installation and usage
README exists but no security mention
→ Add security section or link to SECURITY.md
LICENSE missing
→ Copy LICENSE from another package or repo root
manifest.yaml invalid YAML
→ Check syntax with: python3 -m yaml manifest.yaml
CHANGELOG.md missing (warning only)
→ Create CHANGELOG to track version history
Purpose: Ensure all packages have proper legal licensing
What It Checks:
- Each package has
LICENSEfile - LICENSE files are not empty
- Repository root has LICENSE
Why It Matters:
License files:
- Define legal terms for package use
- Protect maintainers from liability
- Clarify user rights and obligations
- Meet marketplace and legal requirements
- Enable open source distribution
License Requirements:
All Synaptic Canvas packages should use MIT License for consistency:
MIT License
Copyright (c) 2025 Your Name
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
[... full MIT license text ...]
Best Practices:
- Consistent Licensing: Use same license across all packages
- Copy LICENSE: Each package should have its own LICENSE file
- Update Copyright: Use current year and correct author
- Include Full Text: Don't abbreviate or truncate license
- Match README: LICENSE mentioned in README should match actual file
Purpose: Identify vulnerable or outdated dependencies
What It Checks:
- npm dependencies (if package.json exists)
- Python dependencies (if requirements.txt exists)
- Git URLs using insecure protocols
- Known vulnerable package versions
Why It Matters:
Vulnerable dependencies can:
- Introduce security holes into your packages
- Expose user systems to attacks
- Violate security policies
- Damage reputation and trust
npm Audit:
If Node.js packages exist, runs npm audit:
cd project-root
npm audit
# Example output:
# High severity vulnerability in lodash < 4.17.12
# Run npm audit fix to resolvePython Dependencies:
Checks for known vulnerable packages:
- pyyaml < 5.4 (YAML parsing vulnerabilities)
- requests < 2.20.0 (Security issues)
- urllib3 < 1.26.5 (Multiple CVEs)
How to Fix:
# Node.js: Auto-fix vulnerabilities
npm audit fix
# Python: Update to safe versions
pip3 install --upgrade pyyaml requests urllib3
# Verify fixes
npm audit # Should show 0 vulnerabilities
pip3 check # Should show no issuesInsecure Git URLs:
# BAD: Insecure git:// protocol
dependencies:
- git://github.com/user/repo.git
# GOOD: Secure https:// protocol
dependencies:
- https://github.com/user/repo.gitSeverity Levels:
- HIGH: Critical vulnerabilities, known exploits, immediate fix required
- MEDIUM: Moderate risk, should fix soon
- LOW: Minor issues, fix when convenient
Run before committing code:
# Full scan
./scripts/security-scan.py
# Quick scan (faster, skips dependency audit)
./scripts/security-scan.py --quick
# Scan specific package
./scripts/security-scan.py --package your-packageIntegrate into CI/CD pipeline:
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run security scan
run: ./scripts/security-scan.py --json > scan-results.json
- name: Check results
run: |
if [ $? -ne 0 ]; then
echo "Security scan failed"
exit 1
fi
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: security-scan-results
path: scan-results.jsonRun automatically on commit:
# .git/hooks/pre-commit
#!/bin/bash
echo "Running security scan..."
./scripts/security-scan.py --quick
if [ $? -ne 0 ]; then
echo "Security scan failed. Commit aborted."
exit 1
fiMake executable:
chmod +x .git/hooks/pre-commitRun weekly to catch new vulnerabilities:
# .github/workflows/weekly-security.yml
name: Weekly Security Scan
on:
schedule:
- cron: '0 0 * * 0' # Every Sunday at midnight
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run full security scan
run: ./scripts/security-scan.py0 - All checks passed
1 - Warnings found (non-critical issues)
2 - Failures found (critical issues requiring attention)
Text Output (default):
═══════════════════════════════════════════════════════════
Security Scan Report - 2025-12-04T12:34:56Z
═══════════════════════════════════════════════════════════
✅ Secrets Detection: PASSED (0 potential secrets found)
✅ Script Quality: PASSED (all 3 scripts valid)
✅ Python Safety: PASSED (no unsafe patterns found)
✅ Package Documentation: PASSED (all 4 packages have required docs)
✅ License Files: PASSED (all packages have LICENSE)
⚠️ Dependency Audit: WARNING (2 medium severity warnings)
[MEDIUM] Check version of requests (known vulnerabilities in old versions)
─────────────────────────────────────────────────────────
OVERALL STATUS: ⚠️ PASSED (with warnings)
Total Issues Found: 2
Scan Date: 2025-12-04T12:34:56Z
JSON Output:
{
"scan_date": "2025-12-04T12:34:56Z",
"overall_status": "WARNING",
"issues_found": 2,
"checks": {
"secrets_detection": "PASSED",
"script_quality": "PASSED",
"python_safety": "PASSED",
"package_documentation": "PASSED",
"license_files": "PASSED",
"dependency_audit": "WARNING"
},
"scan_configuration": {
"quick_mode": false,
"single_package": null,
"repo_root": "/path/to/repo"
}
}- PASSED ✅: No issues found
- WARNING
⚠️ : Non-critical issues that should be addressed - FAILED ❌: Critical issues requiring immediate attention
- SKIPPED ⊘: Check was skipped (e.g., quick mode)
- HIGH: Critical security risk, fix immediately
- MEDIUM: Moderate risk, plan fix soon
- LOW: Minor issue, fix when convenient
Issue: "shellcheck: command not found"
# Scanner works without shellcheck, but install for better checks
brew install shellcheck # macOS
apt-get install shellcheck # UbuntuIssue: "npm: command not found"
# Dependency audit skipped if npm not installed
# Install Node.js to enable npm audit
brew install node # macOSIssue: "Permission denied: ./scripts/security-scan.py"
# Make script executable
chmod +x scripts/security-scan.pyIssue: "Package not found: my-package"
# Verify package exists
ls packages/my-package
# Check package name spelling
./scripts/security-scan.py --package sc-delay-tasks # Correct nameIf scan flags legitimate code:
- Verify it's actually safe: Double-check the flagged code
- Add comments: Explain why pattern is acceptable
- Refactor if possible: Use safer alternatives
- Document exception: Note in SECURITY.md why it's necessary
Example:
# This eval() is safe because input is sanitized and validated
# against whitelist before evaluation. Used only for math expressions
# in controlled development environment.
if is_safe_math_expression(user_input):
result = eval(user_input)- Run Before Committing: Always scan locally before pushing
- Fix Issues Promptly: Don't accumulate security debt
- Document Exceptions: Explain any flagged patterns
- Keep Dependencies Updated: Regular dependency audits
- Review Scan Results: Understand each finding
- Require Clean Scans: PRs should pass security scan
- Question Exceptions: Verify documented exceptions are legitimate
- Check Fixes: Ensure issues were actually resolved
- Consider Context: Some warnings acceptable in specific contexts
- Fail Fast: Block deployments on security failures
- Store Results: Archive scan results for audit trail
- Notify Team: Alert on new security issues
- Trend Analysis: Track security metrics over time
This section details when and how security scans are performed. Automated security scanning is a key component of our security commitment, helping identify vulnerabilities early and maintain package quality.
What It Includes:
- Secrets detection
- Script quality checks
- Python safety analysis
- Package documentation verification
- License file validation
- Complete dependency audit
Duration: ~2-5 minutes depending on repository size
Command: ./scripts/security-scan.py
What It Includes:
- Secrets detection
- Script quality checks
- Python safety analysis
- Package documentation verification
- License file validation
Excludes: Dependency audit (time-consuming)
Duration: ~30-60 seconds
Command: ./scripts/security-scan.py --quick
Trigger: Git tag creation or version bump
Type: Full security scan
Purpose: Ensure no security issues in released versions
Process:
- Version bump or tag detected
- Automated CI/CD pipeline triggered
- Full security scan executed
- Results recorded in artifacts
- Release blocked if critical issues found
Pass Criteria:
- No HIGH severity issues
- Zero hardcoded secrets
- All packages have required documentation
- All license files present
Failure Action:
- Release blocked
- Maintainer notified
- Issues must be fixed before retry
Schedule: Every Sunday at 00:00 UTC
Type: Full security scan
Purpose: Catch newly discovered vulnerabilities in dependencies
Process:
- GitHub Actions cron trigger
- Full security scan on main branch
- Results compared to previous week
- Report generated and archived
- Notifications sent if new issues found
Why Weekly:
- New CVEs published regularly
- Dependencies may become vulnerable over time
- Catch configuration drift
- Maintain security baseline
Notification:
- GitHub Issues created for new HIGH severity
- Summary in weekly repository digest
- Archived in repository Actions tab
Trigger: PR opened or updated
Type: Quick scan + targeted full scan on changed files
Purpose: Prevent security regressions
Process:
- PR created or updated
- Quick scan runs immediately
- Changed packages get full scan
- Results posted as PR comment
- Checks must pass for merge
Checked:
- Only changed files and packages
- No new secrets introduced
- Script quality maintained
- Documentation updated appropriately
Pass Criteria:
- Quick scan passes
- No new HIGH severity issues
- All checks green
Developer Experience:
- Fast feedback (< 2 minutes)
- Clear actionable results
- Blockers explained with remediation
Trigger: Developer runs script locally
Type: Full or quick (developer choice)
Purpose: Pre-commit validation, troubleshooting
Process:
# Full scan
./scripts/security-scan.py
# Quick scan
./scripts/security-scan.py --quick
# Single package
./scripts/security-scan.py --package sc-delay-tasks
# JSON output
./scripts/security-scan.py --json > results.jsonWhen to Run:
- Before committing changes
- After dependency updates
- When troubleshooting issues
- Before opening PR
Best Practice: Run quick scan pre-commit, full scan pre-PR
Trigger: Security incident or vulnerability report
Type: Comprehensive audit (full scan + manual review)
Purpose: Verify fix completeness and identify related issues
Process:
- Incident reported or detected
- Immediate targeted scan
- Fix developed and applied
- Full scan to verify fix
- Extended manual review
- Additional targeted scans
Scope:
- All packages (not just affected)
- Historical commits if needed
- Related code patterns
- Documentation accuracy
Frequency: Every scan (full and quick)
What We Look For:
- Hardcoded passwords
- API keys and tokens
- AWS/cloud credentials
- Private keys
- Database connection strings
- OAuth secrets
Tools:
- Pattern matching (regex)
- Common secret formats
- Configuration file scanning
Impact: HIGH severity, immediate fix required
Frequency: Every scan (full and quick)
What We Check:
- Executable permissions
- Shebang lines present
- Error handling (
set -e) - Shellcheck validation (if available)
Tools:
- Shellcheck
- Custom validation scripts
- Permission checks
Impact: MEDIUM severity, fix before release
Frequency: Every scan (full and quick)
What We Check:
eval()andexec()callsshell=Truein subprocesspickle.loads()usage- Unsafe deserialization
Tools:
- Pattern matching
- AST analysis (future)
Impact: HIGH severity, immediate fix required
Frequency: Every scan (full and quick)
What We Verify:
- README.md exists
- Security section in README
- LICENSE file present
- manifest.yaml valid
- CHANGELOG.md exists (recommended)
Tools:
- File existence checks
- YAML validation
- Content validation
Impact: HIGH for missing LICENSE, MEDIUM for others
Frequency: Every scan (full and quick)
What We Check:
- LICENSE in each package
- LICENSE not empty
- Repository root LICENSE
Tools:
- File existence checks
- Size validation
Impact: HIGH severity, required for distribution
Frequency: Full scans only (weekly, release, post-incident)
What We Check:
- npm vulnerabilities
- Python package vulnerabilities
- Outdated dependencies
- Insecure git URLs
Tools:
npm audit- Known vulnerability databases
- Version checking
Impact: Varies by severity (HIGH to LOW)
Location: GitHub Actions Artifacts
Format: JSON + text report
Retention: 90 days
Access:
# Via GitHub CLI
gh run list --workflow=security-scan.yml
gh run view RUN_ID
gh run download RUN_IDLocation: PR comments
Format: Formatted text with status emojis
Content:
- Summary of checks
- Failed checks with details
- Remediation guidance
- Links to documentation
Example:
Security Scan Results
Secrets Detection: PASSED
Script Quality: PASSED
Python Safety: FAILED (2 issues)
- eval() call in packages/example/script.py:42
Please fix the issues above before merging.
Location:
- GitHub Release notes
- CI/CD logs
- Archived artifacts
Format:
- Summary in release notes
- Full report in artifacts
Example Release Note:
## Security
All security scans passed
- 0 secrets detected
- 0 unsafe code patterns
- All documentation current
- All dependencies secure
View full scan results in CI artifacts.
Location:
- GitHub Issues (if problems found)
- Repository Actions tab
- Archived artifacts
Format:
- Issue created for new problems
- Weekly summary report
Example Issue:
Title: [Security] Weekly Scan Found 2 New Issues
Weekly security scan on 2025-12-04 found:
1. HIGH: New npm vulnerability in lodash < 4.17.12
- Package: lodash
- Severity: High
- Fix: Update to 4.17.12+
2. MEDIUM: Shellcheck warning in scripts/example.sh
- Line 42: Unquoted variable
- Fix: Add quotes around $variable
See full report: [link to artifacts]
Storage: GitHub Actions artifacts and Issues
Tracked Metrics:
- Total scans run
- Pass/fail rate
- Issues found by type
- Issues fixed
- Mean time to fix
Analysis: Monthly security reports
| Date | Scan Type | Status | Issues Found | Critical Issues |
|---|---|---|---|---|
| 2025-12-04 | Release | PASSED | 0 | 0 |
| 2025-12-03 | PR | PASSED | 2 (LOW) | 0 |
| 2025-12-01 | Weekly | PASSED | 0 | 0 |
| 2025-11-30 | Manual | PASSED | 1 (MEDIUM) | 0 |
| 2025-11-28 | Release | PASSED | 0 | 0 |
Monitored Trends:
- Issue frequency over time
- Types of issues most common
- Time to fix by severity
- Scan pass rate
- Dependency vulnerability rate
Goals:
- Maintain 95%+ pass rate
- < 24 hour fix for critical
- < 1 week fix for high
- Zero hardcoded secrets
- 100% documentation coverage
name: Security Scan
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
release:
types: [created]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run security scan
run: |
chmod +x scripts/security-scan.py
./scripts/security-scan.py --json > scan-results.json
- name: Check results
run: |
if [ $? -eq 2 ]; then
echo "Critical security issues found"
exit 1
fi
- name: Upload results
uses: actions/upload-artifact@v3
if: always()
with:
name: security-scan-results
path: scan-results.json
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('scan-results.json'));
// Post comment with results#!/bin/bash
# .git/hooks/pre-commit
echo "Running quick security scan..."
./scripts/security-scan.py --quick
if [ $? -ne 0 ]; then
echo ""
echo "Security scan failed. Commit aborted."
echo "Fix the issues above or run with --no-verify to skip (not recommended)"
exit 1
fi
echo "Security scan passed"All security scans create an audit trail:
Recorded Information:
- Scan timestamp
- Scan type (full/quick)
- Triggering event
- Results summary
- Issues found
- Actions taken
Retention: 90 days in Actions, longer in Issues
Access: Repository maintainers and auditors
Frequency: Monthly
Content:
- All scans performed
- Issues found and resolved
- Outstanding issues
- Trend analysis
- Compliance status
Distribution: Repository security documentation
Q1 2025:
- SAST (Static Application Security Testing) integration
- Dependency graph analysis
- Automated dependency updates
- Enhanced reporting dashboard
Q2 2025:
- Container scanning (if Docker used)
- Infrastructure as Code scanning
- License compliance checking
- SBOM generation
Q3 2025:
- Security scorecard integration
- Continuous monitoring
- Threat modeling automation
- Security metrics API
- SECURITY.md - Overall security policy
- PUBLISHER-VERIFICATION.md - Publisher verification process
- Shellcheck Documentation
- OWASP Secure Coding Practices
For questions about security scanning:
- Review this guide thoroughly
- Check scan output for specific guidance
- See SECURITY.md for general security policy
- Open GitHub Issue for unresolved questions