Security Comprehensive Monitoring #89
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
| # Comprehensive Security Monitoring Workflow | |
| # Enhanced security monitoring workflow matching Azure DevOps scheduled stage approach. | |
| # Includes dependency staleness, OSSF Scorecard, AIO version checks, | |
| # and comprehensive security analysis for complete supply chain security validation. | |
| # Security Comprehensive Monitoring Workflow - Complete security monitoring suite | |
| # This workflow performs comprehensive security analysis and monitoring. | |
| # Mirrors the Azure DevOps Scheduled stage approach with full security coverage. | |
| # Includes dependency staleness, OSSF scorecard, and AIO version checks. | |
| --- | |
| name: Security Comprehensive Monitoring | |
| 'on': | |
| workflow_call: | |
| inputs: | |
| max-age-days: | |
| description: 'Maximum age in days for dependency staleness check' | |
| required: false | |
| type: number | |
| default: 30 | |
| iac-types: | |
| description: 'Infrastructure types to validate (all, terraform, bicep)' | |
| required: false | |
| type: string | |
| default: 'all' | |
| scorecard-threshold: | |
| description: 'Minimum OSSF Scorecard score threshold' | |
| required: false | |
| type: number | |
| default: 6.0 | |
| pinning-threshold: | |
| description: 'Minimum dependency pinning compliance percentage' | |
| required: false | |
| type: number | |
| default: 85.0 | |
| dashboard-theme: | |
| description: 'Theme for security dashboard' | |
| required: false | |
| type: string | |
| default: 'auto' | |
| fail-on-critical: | |
| description: 'Whether to fail workflow on critical security issues' | |
| required: false | |
| type: boolean | |
| default: false | |
| publish-artifacts: | |
| description: 'Whether to publish security artifacts' | |
| required: false | |
| type: boolean | |
| default: true | |
| outputs: | |
| overall-status: | |
| description: 'Overall security status' | |
| value: ${{ jobs.security-summary.outputs.overall-status }} | |
| scorecard-score: | |
| description: 'OSSF Scorecard score' | |
| value: ${{ jobs.ossf-scorecard.outputs.score }} | |
| pinning-compliance: | |
| description: 'Dependency pinning compliance' | |
| value: ${{ jobs.security-analysis.outputs.pinning-compliance }} | |
| critical-issues: | |
| description: 'Number of critical issues' | |
| value: ${{ jobs.security-summary.outputs.critical-issues }} | |
| deployment-approved: | |
| description: 'Whether deployment is approved based on security status' | |
| value: ${{ jobs.security-summary.outputs.deployment-approved }} | |
| workflow_dispatch: | |
| inputs: | |
| max-age-days: | |
| description: 'Maximum age in days for dependency staleness check' | |
| required: false | |
| type: number | |
| default: 30 | |
| iac-types: | |
| description: 'Infrastructure types to validate (all, terraform, bicep)' | |
| required: false | |
| type: string | |
| default: 'all' | |
| scorecard-threshold: | |
| description: 'Minimum OSSF Scorecard score threshold (0-10)' | |
| required: false | |
| type: number | |
| default: 6.0 | |
| pinning-threshold: | |
| description: 'Minimum dependency pinning compliance percentage (0-100)' | |
| required: false | |
| type: number | |
| default: 85.0 | |
| dashboard-theme: | |
| description: 'Theme for security dashboard (light, dark, auto)' | |
| required: false | |
| type: choice | |
| options: | |
| - auto | |
| - light | |
| - dark | |
| default: 'auto' | |
| fail-on-critical: | |
| description: 'Fail workflow on critical security issues' | |
| required: false | |
| type: boolean | |
| default: false | |
| schedule: | |
| # Run comprehensive security monitoring daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| permissions: | |
| contents: read | |
| security-events: write | |
| actions: read | |
| jobs: | |
| # Security hardening setup for comprehensive monitoring | |
| security-hardening: | |
| name: Security Hardening Setup | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Initialize comprehensive security monitoring | |
| run: | | |
| echo "Comprehensive security monitoring initialized" | |
| echo "Starting comprehensive security validation pipeline..." | |
| # SHA dependency staleness monitoring for supply chain security | |
| dependency-staleness: | |
| name: Dependency Staleness Analysis | |
| runs-on: ubuntu-latest | |
| needs: security-hardening | |
| timeout-minutes: 20 | |
| outputs: | |
| stale-count: ${{ steps.staleness-check.outputs.stale-count }} | |
| threshold-failed: ${{ steps.staleness-check.outputs.threshold-failed }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create logs directory | |
| shell: bash | |
| run: mkdir -p logs | |
| - name: Run dependency staleness check | |
| id: staleness-check | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| $MaxAge = [int]"${{ inputs.max-age-days }}" | |
| Write-Host "Running SHA staleness check with MaxAge=$MaxAge days" | |
| ./scripts/security/Test-SHAStaleness.ps1 ` | |
| -OutputFormat json ` | |
| -MaxAge $MaxAge ` | |
| -LogPath "./logs/sha-staleness-check.log" ` | |
| -OutputPath "./stale-dependencies.json" ` | |
| -ExitOnFailure $false | |
| # Parse results for outputs | |
| if (Test-Path "./stale-dependencies.json") { | |
| $results = Get-Content "./stale-dependencies.json" | ConvertFrom-Json | |
| $staleCount = $results.TotalStaleItems | |
| "stale-count=$staleCount" >> $env:GITHUB_OUTPUT | |
| if ($staleCount -gt 0) { | |
| "threshold-failed=true" >> $env:GITHUB_OUTPUT | |
| Write-Warning "$staleCount stale dependencies found" | |
| } else { | |
| "threshold-failed=false" >> $env:GITHUB_OUTPUT | |
| Write-Host "All dependencies are within staleness threshold" | |
| } | |
| } else { | |
| Write-Error "Error: staleness check failed to generate results" | |
| exit 1 | |
| } | |
| - name: Upload staleness results | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: dependency-staleness-results | |
| path: stale-dependencies.json | |
| retention-days: 30 | |
| # OSSF Scorecard analysis for supply chain security assessment | |
| ossf-scorecard: | |
| name: OSSF Scorecard Analysis | |
| runs-on: ubuntu-latest | |
| needs: security-hardening | |
| timeout-minutes: 25 | |
| outputs: | |
| score: ${{ steps.scorecard-check.outputs.score }} | |
| threshold-failed: ${{ steps.scorecard-check.outputs.threshold-failed }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| persist-credentials: false | |
| - name: Run OSSF Scorecard | |
| uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 | |
| with: | |
| results_file: scorecard-results.sarif | |
| results_format: sarif | |
| publish_results: false | |
| - name: Process scorecard results | |
| id: scorecard-check | |
| run: | | |
| # Extract score from SARIF results | |
| score=$(jq -r '.runs[0].properties.score // "0"' scorecard-results.sarif) | |
| echo "score=$score" >> $GITHUB_OUTPUT | |
| # Check against threshold | |
| threshold=${{ inputs.scorecard-threshold }} | |
| if (( $(echo "$score < $threshold" | bc -l) )); then | |
| echo "threshold-failed=true" >> $GITHUB_OUTPUT | |
| echo "Warning: OSSF Scorecard score ($score) below threshold ($threshold)" | |
| else | |
| echo "threshold-failed=false" >> $GITHUB_OUTPUT | |
| echo "OSSF Scorecard score ($score) meets threshold ($threshold)" | |
| fi | |
| - name: Upload OSSF Scorecard results | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: ossf-scorecard-results | |
| path: scorecard-results.sarif | |
| retention-days: 30 | |
| - name: Upload SARIF results to GitHub Security | |
| if: always() | |
| uses: github/codeql-action/upload-sarif@fe4161a26a8629af62121b670040955b330f9af2 | |
| with: | |
| sarif_file: scorecard-results.sarif | |
| # AIO version checking for comprehensive validation | |
| aio-version-check: | |
| name: AIO Version Validation | |
| runs-on: ubuntu-latest | |
| needs: security-hardening | |
| timeout-minutes: 20 | |
| outputs: | |
| version-issues: ${{ steps.aio-check.outputs.issues }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Setup Python | |
| uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Run AIO version check | |
| id: aio-check | |
| run: | | |
| python scripts/aio-version-checker.py \ | |
| --iac-type ${{ inputs.iac-types }} \ | |
| --output-format json \ | |
| --output-path aio-version-check-results.json | |
| # Parse results for outputs | |
| if [[ -f "aio-version-check-results.json" ]]; then | |
| issues=$(jq '.issues | length' aio-version-check-results.json 2>/dev/null || echo "0") | |
| echo "issues=$issues" >> $GITHUB_OUTPUT | |
| echo "AIO version check completed with $issues issues" | |
| else | |
| echo "issues=0" >> $GITHUB_OUTPUT | |
| echo "AIO version check completed (no results file)" | |
| fi | |
| - name: Upload AIO version results | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: aio-version-check-results | |
| path: aio-version-check-results.json | |
| retention-days: 30 | |
| # Comprehensive dependency pinning analysis | |
| security-analysis: | |
| name: Security Analysis & Dashboard | |
| runs-on: ubuntu-latest | |
| needs: [security-hardening, dependency-staleness, ossf-scorecard, aio-version-check] | |
| timeout-minutes: 25 | |
| outputs: | |
| pinning-compliance: ${{ steps.pinning-analysis.outputs.compliance }} | |
| pinning-threshold-failed: ${{ steps.pinning-analysis.outputs.threshold-failed }} | |
| dashboard-path: ${{ steps.dashboard-generation.outputs.dashboard-path }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup PowerShell Environment | |
| shell: pwsh | |
| run: | | |
| Write-Host "PowerShell Version: $($PSVersionTable.PSVersion)" | |
| # Verify security scripts are available | |
| $securityScriptPath = Join-Path $env:GITHUB_WORKSPACE "scripts/security" | |
| if (-not (Test-Path $securityScriptPath)) { | |
| Write-Error "Security scripts directory not found: $securityScriptPath" | |
| exit 1 | |
| } | |
| - name: Download security analysis results | |
| uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
| with: | |
| path: security-results | |
| - name: Run dependency pinning analysis | |
| id: pinning-analysis | |
| shell: pwsh | |
| run: | | |
| $pinningScript = Join-Path $env:GITHUB_WORKSPACE "scripts/security/Test-DependencyPinning.ps1" | |
| Write-Host "Running comprehensive dependency pinning analysis..." | |
| & $pinningScript ` | |
| -Path "." ` | |
| -OutputPath "./dependency-pinning-report.json" | |
| # Parse pinning results | |
| if (Test-Path "./dependency-pinning-report.json") { | |
| $results = Get-Content "./dependency-pinning-report.json" | ConvertFrom-Json | |
| $compliance = [decimal]$results.ComplianceScore | |
| Write-Host "Dependency Pinning Compliance: $compliance%" | |
| "compliance=$compliance" >> $env:GITHUB_OUTPUT | |
| # Check against threshold | |
| $threshold = [decimal]"${{ inputs.pinning-threshold }}" | |
| if ($compliance -lt $threshold) { | |
| Write-Warning "Pinning compliance ($compliance%) below threshold ($threshold%)" | |
| "threshold-failed=true" >> $env:GITHUB_OUTPUT | |
| } else { | |
| "threshold-failed=false" >> $env:GITHUB_OUTPUT | |
| } | |
| } else { | |
| Write-Error "Dependency pinning analysis failed" | |
| exit 1 | |
| } | |
| - name: Generate comprehensive security dashboard | |
| id: dashboard-generation | |
| shell: pwsh | |
| run: | | |
| $dashboardScript = Join-Path $env:GITHUB_WORKSPACE "scripts/security/New-SecurityDashboard.ps1" | |
| Write-Host "Generating comprehensive security dashboard..." | |
| & $dashboardScript ` | |
| -DataPath "." ` | |
| -OutputFormat "html" ` | |
| -OutputPath "./comprehensive-security-dashboard.html" ` | |
| -ThemeMode "${{ inputs.dashboard-theme }}" ` | |
| -RefreshInterval 0 | |
| # Generate additional formats | |
| & $dashboardScript ` | |
| -DataPath "." ` | |
| -OutputFormat "markdown" ` | |
| -OutputPath "./comprehensive-security-dashboard.md" | |
| & $dashboardScript ` | |
| -DataPath "." ` | |
| -OutputFormat "json" ` | |
| -OutputPath "./comprehensive-security-dashboard.json" | |
| "dashboard-path=./comprehensive-security-dashboard.html" >> $env:GITHUB_OUTPUT | |
| - name: Upload security analysis results | |
| if: inputs.publish-artifacts | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: comprehensive-security-analysis | |
| path: | | |
| ./dependency-pinning-report.json | |
| ./comprehensive-security-dashboard.html | |
| ./comprehensive-security-dashboard.md | |
| ./comprehensive-security-dashboard.json | |
| retention-days: 30 | |
| # Comprehensive security validation summary | |
| security-summary: | |
| name: Comprehensive Security Summary | |
| runs-on: ubuntu-latest | |
| needs: [dependency-staleness, ossf-scorecard, aio-version-check, security-analysis] | |
| if: always() | |
| timeout-minutes: 10 | |
| outputs: | |
| overall-status: ${{ steps.summary.outputs.overall-status }} | |
| critical-issues: ${{ steps.summary.outputs.critical-issues }} | |
| deployment-approved: ${{ steps.summary.outputs.deployment-approved }} | |
| steps: | |
| - name: Generate comprehensive security summary | |
| id: summary | |
| run: | | |
| echo "# Comprehensive Security Monitoring Summary" > comprehensive-security-summary.md | |
| echo "" >> comprehensive-security-summary.md | |
| echo "## Analysis Results" >> comprehensive-security-summary.md | |
| # Collect results | |
| stale_failed="${{ needs.dependency-staleness.outputs.threshold-failed }}" | |
| scorecard_failed="${{ needs.ossf-scorecard.outputs.threshold-failed }}" | |
| pinning_failed="${{ needs.security-analysis.outputs.pinning-threshold-failed }}" | |
| stale_count="${{ needs.dependency-staleness.outputs.stale-count }}" | |
| scorecard_score="${{ needs.ossf-scorecard.outputs.score }}" | |
| pinning_compliance="${{ needs.security-analysis.outputs.pinning-compliance }}" | |
| aio_issues="${{ needs.aio-version-check.outputs.version-issues }}" | |
| echo "- Dependency Staleness: $stale_count stale dependencies" >> comprehensive-security-summary.md | |
| echo "- OSSF Scorecard Score: $scorecard_score/10" >> comprehensive-security-summary.md | |
| echo "- Dependency Pinning: $pinning_compliance%" >> comprehensive-security-summary.md | |
| echo "- AIO Version Issues: $aio_issues" >> comprehensive-security-summary.md | |
| echo "" >> comprehensive-security-summary.md | |
| # Calculate critical issues | |
| critical_issues=0 | |
| if [[ "$stale_failed" == "true" ]]; then critical_issues=$((critical_issues + 1)); fi | |
| if [[ "$scorecard_failed" == "true" ]]; then critical_issues=$((critical_issues + 1)); fi | |
| if [[ "$pinning_failed" == "true" ]]; then critical_issues=$((critical_issues + 1)); fi | |
| if [[ "$aio_issues" -gt "0" ]]; then critical_issues=$((critical_issues + 1)); fi | |
| echo "critical-issues=$critical_issues" >> $GITHUB_OUTPUT | |
| # Determine overall status | |
| if [[ $critical_issues -eq 0 ]]; then | |
| overall_status="Good" | |
| deployment_approved="true" | |
| echo "## Overall Status: ✅ GOOD" >> comprehensive-security-summary.md | |
| echo "All comprehensive security checks passed successfully." >> comprehensive-security-summary.md | |
| elif [[ $critical_issues -le 2 ]]; then | |
| overall_status="Warning" | |
| deployment_approved="false" | |
| echo "## Overall Status: ⚠️ WARNING" >> comprehensive-security-summary.md | |
| echo "Some security issues detected that should be addressed." >> comprehensive-security-summary.md | |
| else | |
| overall_status="Critical" | |
| deployment_approved="false" | |
| echo "## Overall Status: ❌ CRITICAL" >> comprehensive-security-summary.md | |
| echo "Multiple critical security issues detected requiring immediate attention." >> comprehensive-security-summary.md | |
| fi | |
| echo "overall-status=$overall_status" >> $GITHUB_OUTPUT | |
| echo "deployment-approved=$deployment_approved" >> $GITHUB_OUTPUT | |
| cat comprehensive-security-summary.md | |
| - name: Check comprehensive security thresholds | |
| if: inputs.fail-on-critical | |
| run: | | |
| critical_issues="${{ steps.summary.outputs.critical-issues }}" | |
| overall_status="${{ steps.summary.outputs.overall-status }}" | |
| if [[ "$overall_status" == "Critical" ]]; then | |
| echo "❌ Comprehensive security validation failed with $critical_issues critical issues" | |
| echo "Review the comprehensive security dashboard and address all critical issues before proceeding." | |
| exit 1 | |
| else | |
| echo "✅ Comprehensive security validation passed (Status: $overall_status)" | |
| fi | |
| - name: Upload comprehensive security summary | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: comprehensive-security-summary | |
| path: comprehensive-security-summary.md | |
| retention-days: 90 |