Security Scanning #167
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, develop, master, 001-fix-ci-security-failures ] | |
| pull_request: | |
| branches: [ main, master ] | |
| schedule: | |
| # Run security scans daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| workflow_dispatch: | |
| env: | |
| PYTHON_VERSION: "3.12" | |
| jobs: | |
| dependency-scan: | |
| name: Dependency Vulnerability Scan | |
| runs-on: ubuntu-latest | |
| if: false | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Install dependencies | |
| run: | | |
| uv sync --all-extras | |
| - name: Run Safety check | |
| run: | | |
| uv run safety check --json --output safety-report.json || true | |
| uv run safety check --short-report || true | |
| continue-on-error: true | |
| - name: Run pip-audit | |
| run: | | |
| uv run pip-audit --format=json --output=pip-audit-report.json || true | |
| continue-on-error: true | |
| - name: Upload dependency scan results | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: dependency-scan-results | |
| path: | | |
| safety-report.json | |
| pip-audit-report.json | |
| code-security-scan: | |
| name: Code Security Analysis | |
| runs-on: ubuntu-latest | |
| if: false | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Install dependencies | |
| run: | | |
| uv sync --all-extras | |
| - name: Run Bandit security linter | |
| run: | | |
| uv run bandit -r iris_vector_rag/ -x tests/ -f json -o bandit-report.json || true | |
| uv run bandit -r iris_vector_rag/ -x tests/ -f txt -o bandit-report.txt || true | |
| continue-on-error: true | |
| - name: Run semgrep security analysis | |
| uses: returntocorp/semgrep-action@v1 | |
| with: | |
| config: >- | |
| p/security-audit | |
| p/secrets | |
| p/python | |
| p/owasp-top-ten | |
| continue-on-error: true | |
| - name: Upload code security results | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: code-security-results | |
| path: | | |
| bandit-report.json | |
| bandit-report.txt | |
| - name: Upload SARIF file | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() && hashFiles('semgrep.sarif') != '' | |
| with: | |
| sarif_file: semgrep.sarif | |
| continue-on-error: true | |
| secret-scan: | |
| name: Secret Detection | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Run TruffleHog secret scan | |
| uses: trufflesecurity/trufflehog@main | |
| with: | |
| path: ./ | |
| extra_args: --debug --only-verified | |
| continue-on-error: true | |
| - name: Run GitLeaks secret scan | |
| uses: gitleaks/gitleaks-action@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| continue-on-error: true | |
| docker-security-scan: | |
| name: Docker Security Scan | |
| runs-on: ubuntu-latest | |
| if: false | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Build Docker image | |
| run: | | |
| docker build -t iris-vector-rag:security-test . || true | |
| continue-on-error: true | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| if: success() | |
| with: | |
| image-ref: 'iris-vector-rag:security-test' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| continue-on-error: true | |
| - name: Run Trivy filesystem scan | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-fs-results.sarif' | |
| continue-on-error: true | |
| - name: Upload Trivy scan results | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() && (hashFiles('trivy-results.sarif') != '' || hashFiles('trivy-fs-results.sarif') != '') | |
| with: | |
| sarif_file: trivy-fs-results.sarif | |
| continue-on-error: true | |
| - name: Upload Docker security results | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: docker-security-results | |
| path: | | |
| trivy-results.sarif | |
| trivy-fs-results.sarif | |
| infrastructure-scan: | |
| name: Infrastructure Security Scan | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Run Checkov IaC security scan | |
| uses: bridgecrewio/checkov-action@v12 | |
| with: | |
| directory: . | |
| framework: dockerfile | |
| output_format: sarif | |
| output_file_path: checkov-results.sarif | |
| soft_fail: false | |
| - name: Upload Checkov scan results | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() && hashFiles('checkov-results.sarif') != '' | |
| with: | |
| sarif_file: checkov-results.sarif | |
| continue-on-error: true | |
| compliance-check: | |
| name: Compliance & License Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Install dependencies | |
| run: | | |
| uv sync --all-extras | |
| - name: Check license compatibility | |
| run: | | |
| pip install licensecheck | |
| licensecheck --no-deps --zero --format json > license-report.json || true | |
| licensecheck --no-deps --zero || true | |
| continue-on-error: true | |
| - name: Upload compliance results | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: compliance-results | |
| path: | | |
| license-report.json | |
| codeql-analysis: | |
| name: CodeQL Security Analysis | |
| runs-on: ubuntu-latest | |
| if: false | |
| timeout-minutes: 30 | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| language: [ 'python', 'javascript' ] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v4 | |
| with: | |
| languages: ${{ matrix.language }} | |
| queries: security-extended,security-and-quality | |
| - name: Autobuild | |
| uses: github/codeql-action/autobuild@v4 | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v4 | |
| with: | |
| category: "/language:${{matrix.language}}" | |
| security-scorecard: | |
| name: OSSF Security Scorecard | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| permissions: | |
| security-events: write | |
| id-token: write | |
| actions: read | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Run analysis | |
| uses: ossf/[email protected] | |
| with: | |
| results_file: results.sarif | |
| results_format: sarif | |
| publish_results: true | |
| continue-on-error: true | |
| - name: Upload SARIF results | |
| uses: github/codeql-action/upload-sarif@v4 | |
| with: | |
| sarif_file: results.sarif | |
| continue-on-error: true | |
| security-policy-check: | |
| name: Security Policy Validation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Check for security policy | |
| run: | | |
| if [ ! -f SECURITY.md ]; then | |
| echo "⚠️ SECURITY.md file not found (recommended but not required)" | |
| exit 0 | |
| fi | |
| echo "✅ SECURITY.md file exists" | |
| - name: Check for vulnerability disclosure | |
| if: hashFiles('SECURITY.md') != '' | |
| run: | | |
| if ! grep -q "vulnerability" SECURITY.md; then | |
| echo "⚠️ Security policy should include vulnerability disclosure process" | |
| else | |
| echo "✅ Vulnerability disclosure process found" | |
| fi |