name: Security Audit
on:
schedule:
- cron: '0 2 * * *'
workflow_dispatch: push:
branches: [ main ]
paths:
- 'Cargo.lock'
- 'Cargo.toml'
jobs:
audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Run security audit
run: cargo audit --format json | tee audit_output.json
- name: Generate audit report
run: |
echo "## Security Audit Results" > audit_report.md
echo "" >> audit_report.md
echo "| Severity | Count | Description |" >> audit_report.md
echo "|----------|--------|-------------|" >> audit_report.md
cargo audit --format markdown >> audit_report.md || echo "No vulnerabilities found" >> audit_report.md
- name: Create issue on vulnerability detection
if: failure()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const auditData = JSON.parse(fs.readFileSync('audit_output.json', 'utf8'));
if (auditData.vulnerabilities && auditData.vulnerabilities.list.length > 0) {
const issueTitle = `Security Vulnerabilities Detected (${auditData.vulnerabilities.count})`;
const issueBody = fs.readFileSync('audit_report.md', 'utf8');
// Check if issue already exists
const existingIssues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['security', 'vulnerability'],
state: 'open'
});
const existingIssue = existingIssues.data.find(issue =>
issue.title.includes('Security Vulnerabilities Detected')
);
if (!existingIssue) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: issueTitle,
body: issueBody,
labels: ['security', 'vulnerability', 'automated']
});
}
}
- name: Upload audit artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: security-audit-report
path: audit_report.md