Security Audit #229
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
| name: Security Audit | |
| on: | |
| push: | |
| branches: [ "main", "develop" ] | |
| # Feature branches can be tested via pull requests | |
| pull_request: | |
| branches: [ "main", "develop" ] | |
| schedule: | |
| # Run security audit daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| audit_level: | |
| description: 'Security audit level' | |
| required: true | |
| default: 'comprehensive' | |
| type: choice | |
| options: | |
| - basic | |
| - comprehensive | |
| - paranoid | |
| build_profile: | |
| description: 'Build profile for CodeQL analysis' | |
| required: false | |
| default: 'release-secure' | |
| type: string | |
| security_features: | |
| description: 'Security features to enable' | |
| required: false | |
| default: 'security-hardened' | |
| type: string | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_NET_RETRY: 10 | |
| RUSTUP_MAX_RETRIES: 10 | |
| jobs: | |
| security-audit: | |
| name: Security Audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy, rustfmt | |
| - name: Cache cargo dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-security-audit-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-security-audit- | |
| ${{ runner.os }}-cargo- | |
| - name: Install security tools | |
| run: | | |
| echo "🔧 Installing security tools..." | |
| cargo install cargo-audit --features=fix || true | |
| cargo install cargo-deny || true | |
| cargo install cargo-outdated || true | |
| cargo install cargo-geiger || true | |
| echo "✅ Security tools installed" | |
| - name: Validate security configuration | |
| run: | | |
| echo "🔒 Validating security configuration..." | |
| make -f Makefile.security security-validate-config | |
| - name: Run cargo audit | |
| run: | | |
| echo "🔍 Running security vulnerability audit..." | |
| # Configuration is read from audit.toml | |
| cargo audit --json > security-audit-report.json | |
| if [ $? -ne 0 ]; then | |
| echo "❌ CRITICAL: Security vulnerabilities detected!" | |
| cat security-audit-report.json | |
| exit 1 | |
| fi | |
| echo "✅ No security vulnerabilities found" | |
| - name: Track unmaintained dependencies | |
| run: | | |
| echo "📊 Tracking unmaintained dependencies..." | |
| # Run audit with warnings to capture unmaintained dependencies | |
| cargo audit --format json --quiet > unmaintained-audit.json 2>/dev/null || true | |
| # Extract unmaintained dependencies for reporting | |
| if command -v jq >/dev/null 2>&1; then | |
| echo "## Unmaintained Dependencies Report" > unmaintained-report.md | |
| echo "Generated: $(date)" >> unmaintained-report.md | |
| echo "" >> unmaintained-report.md | |
| # Check if there are any unmaintained warnings | |
| UNMAINTAINED_COUNT=$(jq -r '.warnings // [] | length' unmaintained-audit.json 2>/dev/null || echo "0") | |
| if [ "$UNMAINTAINED_COUNT" -gt 0 ]; then | |
| echo "⚠️ Found $UNMAINTAINED_COUNT unmaintained dependencies:" >> unmaintained-report.md | |
| jq -r '.warnings[]? | "- **\(.package.name)** v\(.package.version): \(.advisory.title)"' unmaintained-audit.json >> unmaintained-report.md 2>/dev/null || true | |
| else | |
| echo "✅ No unmaintained dependencies detected" >> unmaintained-report.md | |
| fi | |
| cat unmaintained-report.md | |
| else | |
| echo "⚠️ jq not available - skipping detailed unmaintained dependency analysis" | |
| cargo audit 2>&1 | grep -E "(unmaintained|Warning)" || echo "✅ No unmaintained warnings found" | |
| fi | |
| - name: Run dependency policy checks | |
| run: | | |
| echo "📋 Running dependency policy checks..." | |
| # Run cargo deny check and capture exit code | |
| set +e # Don't exit on error | |
| cargo deny check > deny-output.txt 2>&1 | |
| DENY_EXIT_CODE=$? | |
| set -e # Re-enable exit on error | |
| # Display the output | |
| cat deny-output.txt | |
| # Check exit code: 0 = success, 1 = errors, 2 = warnings only | |
| if [ $DENY_EXIT_CODE -eq 0 ]; then | |
| echo "✅ All dependency policies passed" | |
| elif [ $DENY_EXIT_CODE -eq 2 ]; then | |
| echo "⚠️ Warnings found but no critical errors - continuing" | |
| else | |
| echo "❌ CRITICAL: Dependency policy violations detected!" | |
| exit 1 | |
| fi | |
| - name: Check for outdated dependencies with security focus | |
| run: | | |
| echo "📅 Checking for outdated dependencies with security implications..." | |
| cargo outdated --exit-code 1 || echo "⚠️ Some dependencies are outdated - security review recommended" | |
| - name: Run LDAP-specific security validation | |
| run: | | |
| echo "🔐 Running LDAP-specific security validation..." | |
| # Check LDAP authentication code for security issues | |
| cargo clippy --features ldap-auth -- \ | |
| -W clippy::arithmetic_side_effects \ | |
| -W clippy::panic \ | |
| -W clippy::unwrap_used \ | |
| -W clippy::expect_used | |
| echo "✅ LDAP security validation passed" | |
| - name: Run comprehensive security check | |
| run: | | |
| echo "🛡️ Running comprehensive security check..." | |
| ./scripts/security-check.sh | |
| - name: Generate security report | |
| run: | | |
| echo "📊 Generating security report..." | |
| make -f Makefile.security security-report | |
| - name: Upload security reports | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: security-audit-reports | |
| path: | | |
| security-audit-report.json | |
| security-geiger-report.md | |
| unmaintained-audit.json | |
| unmaintained-report.md | |
| reports/ | |
| dependency-review: | |
| name: Dependency Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Dependency Review | |
| uses: actions/dependency-review-action@v4 | |
| with: | |
| # All configuration is centralized in the config file | |
| config-file: .github/dependency-review-config.yml | |
| - name: Comprehensive License Check with cargo-deny | |
| run: | | |
| echo "🔄 Running comprehensive license check with cargo-deny..." | |
| cargo install cargo-deny || true | |
| echo "📋 Checking license compliance..." | |
| cargo deny check licenses | |
| echo "📊 License summary:" | |
| cargo tree --format "{p} {l}" | sort | uniq -c | sort -nr | head -10 | |
| echo "✅ License check completed successfully" | |
| - name: LDAP dependency security check | |
| run: | | |
| echo "🔐 Checking LDAP-related dependencies for security issues..." | |
| cargo tree --features ldap-auth | grep -E "(ldap|tls|ssl)" || true | |
| echo "✅ LDAP dependency review completed" | |
| codeql-analysis: | |
| name: CodeQL Analysis | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v3 | |
| with: | |
| languages: rust | |
| queries: security-and-quality | |
| config-file: .github/codeql/codeql-config.yml | |
| - name: Setup Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - name: Setup protoc | |
| uses: arduino/setup-protoc@v3 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Security-hardened build for analysis | |
| run: | | |
| echo "🔨 Building with security features for CodeQL analysis..." | |
| BUILD_PROFILE="${{ github.event.inputs.build_profile || 'release-secure' }}" | |
| SECURITY_FEATURES="${{ github.event.inputs.security_features || 'security-hardened' }}" | |
| echo "Using build profile: $BUILD_PROFILE" | |
| echo "Using security features: $SECURITY_FEATURES" | |
| cargo build --profile "$BUILD_PROFILE" --features "$SECURITY_FEATURES" | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v3 | |
| with: | |
| category: "/language:rust" | |
| - name: LDAP-specific security analysis | |
| run: | | |
| echo "🔐 Running LDAP-specific security analysis..." | |
| # Check for common LDAP security issues | |
| grep -r "ldap" src/ --include="*.rs" | grep -E "(password|secret|bind)" || echo "No obvious LDAP security issues found" | |
| echo "✅ LDAP security analysis completed" | |
| supply-chain-security: | |
| name: Supply Chain Security | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| severity: 'CRITICAL,HIGH,MEDIUM' | |
| - name: Run Trivy for Rust dependencies | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: './Cargo.lock' | |
| format: 'table' | |
| output: 'trivy-rust-deps.txt' | |
| - name: Check for LDAP-specific vulnerabilities | |
| run: | | |
| echo "🔐 Checking for LDAP-specific vulnerabilities..." | |
| # Check if any LDAP-related dependencies have known vulnerabilities | |
| if grep -i "ldap" trivy-rust-deps.txt; then | |
| echo "⚠️ LDAP-related dependencies found in vulnerability scan" | |
| else | |
| echo "✅ No LDAP-specific vulnerabilities detected" | |
| fi | |
| - name: Upload Trivy scan results | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| - name: Upload Trivy reports | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: trivy-security-reports | |
| path: | | |
| trivy-results.sarif | |
| trivy-rust-deps.txt | |
| security-summary: | |
| name: Security Audit Summary | |
| runs-on: ubuntu-latest | |
| needs: [security-audit, dependency-review, codeql-analysis, supply-chain-security] | |
| if: always() | |
| steps: | |
| - name: Generate security summary | |
| run: | | |
| echo "# Security Audit Summary" > security-summary.md | |
| echo "" >> security-summary.md | |
| echo "**Date**: $(date)" >> security-summary.md | |
| echo "**Branch**: ${{ github.ref_name }}" >> security-summary.md | |
| echo "**Commit**: ${{ github.sha }}" >> security-summary.md | |
| echo "" >> security-summary.md | |
| echo "## Results" >> security-summary.md | |
| echo "- Security Audit: ${{ needs.security-audit.result }}" >> security-summary.md | |
| echo "- Dependency Review: ${{ needs.dependency-review.result }}" >> security-summary.md | |
| echo "- CodeQL Analysis: ${{ needs.codeql-analysis.result }}" >> security-summary.md | |
| echo "- Supply Chain Security: ${{ needs.supply-chain-security.result }}" >> security-summary.md | |
| echo "" >> security-summary.md | |
| if [[ "${{ needs.security-audit.result }}" == "success" && | |
| "${{ needs.codeql-analysis.result }}" == "success" && | |
| "${{ needs.supply-chain-security.result }}" == "success" ]]; then | |
| echo "## ✅ Overall Status: PASSED" >> security-summary.md | |
| echo "All security checks have passed successfully." >> security-summary.md | |
| else | |
| echo "## ❌ Overall Status: FAILED" >> security-summary.md | |
| echo "One or more security checks have failed. Please review and fix issues." >> security-summary.md | |
| fi | |
| - name: Upload security summary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-audit-summary | |
| path: security-summary.md |