name: Security on: push: branches: [main] pull_request: branches: [main] schedule: # Run security scans daily at 2 AM UTC - cron: '0 2 * * *' workflow_dispatch: jobs: vulnerability-scan: name: Vulnerability Scan runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout code uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: "go.mod" - name: Install libpcap run: sudo apt-get install -y libpcap-dev - name: Install govulncheck run: go install golang.org/x/vuln/cmd/govulncheck@latest - name: Run govulncheck (Official Go vulnerability scanner) run: | echo "::group::Running govulncheck" govulncheck ./... echo "::endgroup::" static-analysis: name: Static Security Analysis runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout code uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: "go.mod" - name: Install libpcap run: sudo apt-get install -y libpcap-dev - name: Install static analysis tools run: | go install honnef.co/go/tools/cmd/staticcheck@latest - name: Run staticcheck security analysis run: | echo "::group::Running staticcheck" staticcheck ./... echo "::endgroup::" - name: Run Semgrep security analysis uses: semgrep/semgrep-action@713efdd345f3035192eaa63f56867b88e63e4e5d # v1 (no v1.x.y semver tag exists) with: config: >- p/security-audit p/secrets p/golang generateSarif: "1" continue-on-error: true - name: Upload Semgrep SARIF results if: always() uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: sarif_file: semgrep.sarif continue-on-error: true dependency-review: name: Dependency Review runs-on: ubuntu-latest permissions: contents: read if: github.event_name == 'pull_request' steps: - name: Checkout code uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Dependency Review uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 with: fail-on-severity: moderate allow-ghsas: GHSA-xxxx-xxxx-xxxx # Add specific allowlisted advisories if needed deny-licenses: GPL-2.0, LGPL-2.0 # Add licenses to deny if needed security-summary: name: Security Summary runs-on: ubuntu-latest needs: [vulnerability-scan, static-analysis] if: always() permissions: contents: read steps: - name: Security scan summary run: | echo "## Security Scan Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY if [[ "${{ needs.vulnerability-scan.result }}" == "success" ]]; then echo "✅ **Vulnerability Scan**: PASSED" >> $GITHUB_STEP_SUMMARY else echo "❌ **Vulnerability Scan**: FAILED" >> $GITHUB_STEP_SUMMARY fi if [[ "${{ needs.static-analysis.result }}" == "success" ]]; then echo "✅ **Static Analysis**: PASSED" >> $GITHUB_STEP_SUMMARY else echo "❌ **Static Analysis**: FAILED" >> $GITHUB_STEP_SUMMARY fi echo "" >> $GITHUB_STEP_SUMMARY echo "For detailed results, check the individual job logs above." >> $GITHUB_STEP_SUMMARY - name: Fail on security issues if: needs.vulnerability-scan.result == 'failure' || needs.static-analysis.result == 'failure' run: | echo "Security scan detected issues. Please review the results above." exit 1