Skip to content

Security Scan

Security Scan #49

Workflow file for this run

name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run security scan weekly on Monday at 4 AM UTC
- cron: '0 4 * * 1'
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run Safety check
run: |
safety check --json --output safety-report.json
continue-on-error: true
- name: Run Bandit security scan
run: |
bandit -r . -f json -o bandit-report.json --exclude ./.venv,./tests
continue-on-error: true
- name: Upload security reports
uses: actions/upload-artifact@v3
if: always()
with:
name: security-reports
path: |
safety-report.json
bandit-report.json
retention-days: 30
- name: Comment PR with security findings
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
// Read reports if they exist
let safetyIssues = [];
let banditIssues = [];
try {
const safetyReport = JSON.parse(fs.readFileSync('safety-report.json', 'utf8'));
safetyIssues = safetyReport.vulnerabilities || [];
} catch (e) {}
try {
const banditReport = JSON.parse(fs.readFileSync('bandit-report.json', 'utf8'));
banditIssues = banditReport.results || [];
} catch (e) {}
let comment = '## 🔒 Security Scan Results\n\n';
if (safetyIssues.length === 0 && banditIssues.length === 0) {
comment += '✅ No security issues found!';
} else {
if (safetyIssues.length > 0) {
comment += `### Dependency Vulnerabilities (Safety)\n`;
comment += `Found ${safetyIssues.length} vulnerable dependencies\n\n`;
}
if (banditIssues.length > 0) {
comment += `### Code Security Issues (Bandit)\n`;
comment += `Found ${banditIssues.length} potential security issues\n\n`;
}
comment += 'Please review the uploaded artifacts for details.';
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});