Security #147
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 Core - Security Scanning | |
| # Dependency audits, license checks, SAST, secret scanning | |
| name: Security | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| schedule: | |
| # Run daily at 00:00 UTC | |
| - 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: | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Dependency Vulnerability Scanning | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| 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: cargo audit --deny warnings | |
| - name: Generate audit report | |
| if: always() | |
| run: | | |
| cargo audit --json > audit-report.json || true | |
| - name: Upload audit report | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4 | |
| with: | |
| name: security-audit-report | |
| path: audit-report.json | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Supply Chain Security with cargo-deny | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| 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 }} | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # License Compliance Check | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| license-check: | |
| name: "License Check" | |
| 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-license | |
| run: cargo install cargo-license | |
| - name: Generate license report | |
| run: | | |
| cargo license --json > licenses.json | |
| cargo license --tsv > licenses.tsv | |
| - name: Check for GPL licenses | |
| run: | | |
| if grep -i "GPL" licenses.tsv; then | |
| echo "❌ GPL licenses found (incompatible with Apache 2.0)" | |
| exit 1 | |
| else | |
| echo "✅ No GPL licenses found" | |
| fi | |
| - name: Upload license report | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4 | |
| with: | |
| name: license-report | |
| path: | | |
| licenses.json | |
| licenses.tsv | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Secret Scanning with Gitleaks | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| gitleaks: | |
| name: "Secret Scanning" | |
| runs-on: ubuntu-latest | |
| 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 }} | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Static Application Security Testing (SAST) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| clippy-security: | |
| name: "Clippy Security Lints" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # stable | |
| with: | |
| toolchain: stable | |
| components: clippy | |
| - name: Cache cargo | |
| uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-security-${{ hashFiles('**/Cargo.lock') }} | |
| - name: Run security-focused Clippy lints | |
| run: | | |
| cargo clippy --all-features -- \ | |
| -W clippy::suspicious \ | |
| -W clippy::perf \ | |
| -W clippy::correctness \ | |
| -W clippy::unwrap_used \ | |
| -W clippy::expect_used \ | |
| -W clippy::panic \ | |
| -W clippy::todo \ | |
| -W clippy::unimplemented | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Semgrep SAST Scanning | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| semgrep: | |
| name: "Semgrep SAST" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 | |
| - name: Run Semgrep | |
| uses: returntocorp/semgrep-action@713efdd345f3035192eaa63f56867b88e63e4e5d # v1 | |
| with: | |
| config: >- | |
| p/rust | |
| p/security-audit | |
| p/secrets | |
| continue-on-error: true | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # SBOM Generation | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| sbom: | |
| name: "SBOM Generation" | |
| 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-sbom | |
| run: cargo install cargo-sbom | |
| - name: Generate SBOM (CycloneDX) | |
| run: cargo sbom --output-format cyclone_dx_json_1_4 > sbom-cyclonedx.json | |
| - name: Generate SBOM (SPDX) | |
| run: cargo sbom --output-format spdx_json_2_3 > sbom-spdx.json | |
| - name: Upload SBOM | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4 | |
| with: | |
| name: sbom | |
| path: | | |
| sbom-cyclonedx.json | |
| sbom-spdx.json | |
| - name: Attach SBOM to release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| uses: softprops/action-gh-release@26994186c0ac3ef5cae75ac16aa32e8153525f77 # v1 | |
| with: | |
| files: | | |
| sbom-cyclonedx.json | |
| sbom-spdx.json | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Dependency Review (PR only) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| 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 | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| security-summary: | |
| name: "Security Summary" | |
| runs-on: ubuntu-latest | |
| needs: [cargo-audit, cargo-deny, license-check, gitleaks, clippy-security] | |
| 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 "| License Check | ${{ needs.license-check.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Secret Scanning | ${{ needs.gitleaks.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Clippy Security | ${{ needs.clippy-security.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ needs.cargo-audit.result }}" = "success" ] && \ | |
| [ "${{ needs.cargo-deny.result }}" = "success" ] && \ | |
| [ "${{ needs.license-check.result }}" = "success" ] && \ | |
| [ "${{ needs.gitleaks.result }}" = "success" ]; then | |
| echo "✅ **All security checks passed!**" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ **Some security checks failed. Review above.**" >> $GITHUB_STEP_SUMMARY | |
| fi |