Security #68
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ReasonKit Mem - Security Scanning | |
| # Dependency audits, license checks, secret scanning | |
| name: Security | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| schedule: | |
| - cron: "0 0 * * *" | |
| workflow_dispatch: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| # Override .cargo/config.toml target-cpu=native to prevent SIGILL on different runners | |
| CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: "" | |
| jobs: | |
| cargo-audit: | |
| name: "Cargo Audit" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # stable | |
| with: | |
| toolchain: stable | |
| - name: Install cargo-audit | |
| run: cargo install cargo-audit --locked | |
| - name: Run security audit | |
| run: | | |
| # Run audit and capture output | |
| cargo audit --json > audit.json 2>&1 || true | |
| # Check for critical/high severity vulnerabilities only | |
| CRITICAL=$(jq '[.vulnerabilities.list[]? | select(.advisory.severity == "critical")] | length' audit.json 2>/dev/null || echo "0") | |
| HIGH=$(jq '[.vulnerabilities.list[]? | select(.advisory.severity == "high")] | length' audit.json 2>/dev/null || echo "0") | |
| echo "Critical vulnerabilities: $CRITICAL" | |
| echo "High vulnerabilities: $HIGH" | |
| # Fail only on critical/high (warnings handled by cargo-deny) | |
| if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then | |
| echo "❌ Critical or high severity vulnerabilities found" | |
| cat audit.json | jq '.vulnerabilities.list[]? | select(.advisory.severity == "critical" or .advisory.severity == "high")' | |
| exit 1 | |
| fi | |
| echo "✅ No critical/high vulnerabilities found" | |
| cargo-deny: | |
| name: "Cargo Deny" | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| checks: [advisories, licenses, bans, sources] | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 | |
| - name: Run cargo-deny (${{ matrix.checks }}) | |
| uses: EmbarkStudios/cargo-deny-action@3f4a782664881cf5725d0ffd23969fcce89fd868 # v1 | |
| with: | |
| log-level: warn | |
| command: check ${{ matrix.checks }} | |
| gitleaks: | |
| name: "Secret Scanning" | |
| runs-on: ubuntu-latest | |
| # Note: Gitleaks requires GITLEAKS_LICENSE for organization repos | |
| # This step continues on error to not block CI for org repos without license | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Run Gitleaks | |
| uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} | |
| - name: Gitleaks license info | |
| if: failure() | |
| run: | | |
| echo "::notice::Gitleaks requires GITLEAKS_LICENSE secret for organization repos." | |
| echo "::notice::See: https://github.com/gitleaks/gitleaks-action#environment-variables" | |
| dependency-review: | |
| name: "Dependency Review" | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 | |
| - name: Dependency Review | |
| uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4 | |
| with: | |
| fail-on-severity: moderate | |
| deny-licenses: GPL-3.0, AGPL-3.0 | |
| security-summary: | |
| name: "Security Summary" | |
| runs-on: ubuntu-latest | |
| needs: [cargo-audit, cargo-deny, gitleaks] | |
| if: always() | |
| steps: | |
| - name: Generate summary | |
| run: | | |
| echo "## 🔒 Security Scan Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Cargo Audit | ${{ needs.cargo-audit.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Cargo Deny | ${{ needs.cargo-deny.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Secret Scanning | ${{ needs.gitleaks.result == 'success' && '✅ Pass' || '⚠️ Skipped (license)' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ needs.cargo-audit.result }}" = "success" ] && \ | |
| [ "${{ needs.cargo-deny.result }}" = "success" ]; then | |
| echo "✅ **All required security checks passed!**" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ **Some security checks failed. Review above.**" >> $GITHUB_STEP_SUMMARY | |
| fi |