Security Scanning #83
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 Scanning | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| schedule: | |
| - cron: '0 6 * * 1' # Weekly on Mondays | |
| permissions: | |
| contents: read | |
| security-events: write | |
| actions: read | |
| jobs: | |
| codeql: | |
| name: CodeQL Analysis | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| actions: read | |
| continue-on-error: true | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| language: [ 'csharp' ] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v3 | |
| with: | |
| languages: ${{ matrix.language }} | |
| queries: security-and-quality | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.0.x' | |
| - name: Restore dependencies | |
| run: dotnet restore AzureDevOps.MCP.slnx | |
| - name: Build | |
| run: dotnet build AzureDevOps.MCP.slnx --configuration Release --no-restore | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v3 | |
| with: | |
| category: "/language:${{matrix.language}}" | |
| dependency-review: | |
| name: Dependency Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Dependency Review | |
| uses: actions/dependency-review-action@v4 | |
| with: | |
| fail-on-severity: moderate | |
| allow-licenses: MIT, Apache-2.0, BSD-3-Clause, BSD-2-Clause, ISC, LGPL-2.1, LGPL-3.0 | |
| secrets-scan: | |
| name: Secrets Scanning | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: TruffleHog OSS | |
| uses: trufflesecurity/trufflehog@main | |
| with: | |
| path: ./ | |
| base: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || 'HEAD~1' }} | |
| head: HEAD | |
| extra_args: --debug --only-verified | |
| container-scan: | |
| name: Container Security Scan | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build Docker image | |
| run: docker build -t azuredevops-mcp:test . | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: 'azuredevops-mcp:test' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| - name: Upload Trivy scan results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| security-policy-check: | |
| name: Security Policy Compliance | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check for security policy | |
| run: | | |
| if [ ! -f "SECURITY.md" ]; then | |
| echo "⚠️ Security policy not found. Please create SECURITY.md" | |
| exit 1 | |
| fi | |
| echo "✅ Security policy found" | |
| - name: Check for dependabot config | |
| run: | | |
| if [ ! -f ".github/dependabot.yml" ]; then | |
| echo "⚠️ Dependabot configuration not found" | |
| exit 1 | |
| fi | |
| echo "✅ Dependabot configuration found" | |
| - name: Validate security configurations | |
| run: | | |
| # Check for sensitive files that shouldn't be committed | |
| SENSITIVE_FILES=("*.key" "*.pem" "*.p12" "*.pfx" ".env.local" ".env.development" ".env.production" "secrets.json") | |
| for pattern in "${SENSITIVE_FILES[@]}"; do | |
| if find . -name "$pattern" -not -path "./.git/*" | grep -q .; then | |
| echo "⚠️ Found potentially sensitive files matching: $pattern" | |
| find . -name "$pattern" -not -path "./.git/*" | |
| exit 1 | |
| fi | |
| done | |
| # Check for secrets in appsettings files | |
| if grep -r "\".*password.*\":\s*\"[^\"]*[a-zA-Z0-9]" src/ --include="appsettings*.json" 2>/dev/null; then | |
| echo "⚠️ Found potential hardcoded passwords in appsettings files" | |
| exit 1 | |
| fi | |
| echo "✅ Security configuration validation complete" |