name: Security Audit
on:
pull_request:
branches: [main]
push:
branches: [main]
schedule:
- cron: '0 2 * * *'
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
CARGO_TOOLCHAIN: stable
jobs:
security-audit:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ env.CARGO_TOOLCHAIN }}
- name: Cache Cargo build files
uses: Swatinem/rust-cache@v2
- name: Install cargo-audit and cargo-deny
uses: taiki-e/install-action@v2
with:
tool: cargo-audit,cargo-deny
- name: Audit dependencies for security vulnerabilities
run: |
echo "## Security Audit Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Run cargo audit and capture output
echo "### Vulnerability Scan (cargo audit)" >> $GITHUB_STEP_SUMMARY
if cargo audit --json > audit-results.json; then
echo "✅ No security vulnerabilities found" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Security vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "```json" >> $GITHUB_STEP_SUMMARY
cat audit-results.json >> $GITHUB_STEP_SUMMARY
echo "```" >> $GITHUB_STEP_SUMMARY
fi
- name: Check licenses and supply chain
run: |
echo "### Supply Chain Analysis (cargo deny)" >> $GITHUB_STEP_SUMMARY
# Check licenses
if cargo deny check licenses --log-level warn; then
echo "✅ All licenses are approved" >> $GITHUB_STEP_SUMMARY
else
echo "❌ License issues detected" >> $GITHUB_STEP_SUMMARY
fi
# Check for banned/duplicate dependencies
if cargo deny check bans --log-level warn; then
echo "✅ No banned or problematic dependencies" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Dependency issues detected" >> $GITHUB_STEP_SUMMARY
fi
# Check sources
if cargo deny check sources --log-level warn; then
echo "✅ All dependency sources are approved" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Unapproved dependency sources detected" >> $GITHUB_STEP_SUMMARY
fi
- name: Upload security report
uses: actions/upload-artifact@v4
if: always()
with:
name: security-audit-report
path: |
audit-results.json
retention-days: 30
- name: Check for critical vulnerabilities
run: |
if [ -f audit-results.json ]; then
# Count by severity level
CRITICAL_COUNT=$(cat audit-results.json | jq '[.vulnerabilities[]? | select(.advisory.severity == "Critical")] | length' 2>/dev/null || echo "0")
HIGH_COUNT=$(cat audit-results.json | jq '[.vulnerabilities[]? | select(.advisory.severity == "High")] | length' 2>/dev/null || echo "0")
MEDIUM_COUNT=$(cat audit-results.json | jq '[.vulnerabilities[]? | select(.advisory.severity == "Medium")] | length' 2>/dev/null || echo "0")
if [ "$CRITICAL_COUNT" -gt "0" ] || [ "$HIGH_COUNT" -gt "0" ]; then
echo "❌ Found $CRITICAL_COUNT critical and $HIGH_COUNT high security vulnerabilities"
echo "Please review and update vulnerable dependencies"
exit 1
elif [ "$MEDIUM_COUNT" -gt "0" ]; then
echo "⚠️ Found $MEDIUM_COUNT medium security vulnerabilities"
echo "Recommendation: Review and update vulnerable dependencies soon"
else
echo "✅ No critical, high, or medium security vulnerabilities found"
fi
fi