name: Security Scan on: push: branches: [main, develop] pull_request: branches: [main, develop] schedule: # Run security scan weekly on Sundays at 00:00 UTC - cron: '0 0 * * 0' permissions: security-events: write contents: read actions: read jobs: security: name: Security Analysis runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - name: Setup Go uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 with: go-version: '1.23' - name: Cache Go modules uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 with: path: | ~/.cache/go-build ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- # Security Scanning with gosec - name: Run gosec Security Scanner uses: securecodewarrior/github-action-gosec@master with: args: '-fmt sarif -out gosec-results.sarif ./...' - name: Upload gosec results to GitHub Security tab uses: github/codeql-action/upload-sarif@df559355d593797519d70b90fc8edd5db049e7a2 # v3 if: always() with: sarif_file: gosec-results.sarif # Dependency Vulnerability Scanning - name: Run govulncheck run: | go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck -json ./... > govulncheck-results.json || true - name: Parse govulncheck results run: | if [ -s govulncheck-results.json ]; then echo "::warning::Vulnerability check completed. Check govulncheck-results.json for details." if grep -q '"finding"' govulncheck-results.json; then echo "::error::Vulnerabilities found in dependencies!" cat govulncheck-results.json exit 1 fi fi # Additional Security Linting - name: Run security-focused golangci-lint run: | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest golangci-lint run --enable=gosec,gocritic,bodyclose,rowserrcheck,misspell,unconvert,unparam,unused \ --timeout=5m # Makefile Linting - name: Run checkmake on Makefile run: | go install github.com/mrtazz/checkmake/cmd/checkmake@latest checkmake --config=.checkmake Makefile # Shell Script Formatting Check - name: Check shell script formatting run: | go install mvdan.cc/sh/v3/cmd/shfmt@latest shfmt -d . # YAML Linting - name: Run YAML linting run: | go install github.com/excilsploft/yamllint@latest yamllint -c .yamllint . # Secrets Detection (basic patterns) - name: Run secrets detection run: | echo "Scanning for potential secrets..." # Look for common secret patterns git log --all --full-history -- . | grep -i -E "(password|secret|key|token|api_key)" || true find . -type f -name "*.go" -exec grep -H -i -E "(password|secret|key|token|api_key)\s*[:=]" {} \; || true # Check for hardcoded IPs and URLs - name: Check for hardcoded network addresses run: | echo "Scanning for hardcoded network addresses..." find . -type f -name "*.go" -exec grep -H -E "([0-9]{1,3}\.){3}[0-9]{1,3}" {} \; || true find . -type f -name "*.go" -exec grep -H -E "https?://[^/\s]+" {} \; | \ grep -v "example.com|localhost|127.0.0.1" || true # Docker Security (if Dockerfile exists) - name: Run Docker security scan if: hashFiles('Dockerfile') != '' run: | docker run --rm -v "$PWD":/workspace \ aquasec/trivy:latest fs --security-checks vuln,config /workspace/Dockerfile || true # SAST with CodeQL (if available) - name: Initialize CodeQL if: github.event_name != 'schedule' uses: github/codeql-action/init@df559355d593797519d70b90fc8edd5db049e7a2 # v3 with: languages: go - name: Autobuild if: github.event_name != 'schedule' uses: github/codeql-action/autobuild@df559355d593797519d70b90fc8edd5db049e7a2 # v3 - name: Perform CodeQL Analysis if: github.event_name != 'schedule' uses: github/codeql-action/analyze@df559355d593797519d70b90fc8edd5db049e7a2 # v3 # Upload artifacts for review - name: Upload security scan results uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: always() with: name: security-scan-results path: | gosec-results.sarif govulncheck-results.json retention-days: 30