Skip to content

GCP AI Rule hardening - final part (#171) #340

GCP AI Rule hardening - final part (#171)

GCP AI Rule hardening - final part (#171) #340

Workflow file for this run

name: Security Scanning
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch: # Manual trigger
jobs:
dependency-scan:
name: Dependency Vulnerability Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install project dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[all]"
# Freeze before pip-audit is installed so its own transitive deps
# (rich → pygments etc.) are not included in the audit scope.
pip freeze --exclude-editable > project-requirements.txt
- name: Install security scanning tools
run: |
pip install pip-audit
- name: pip-audit (Fail on vulnerabilities)
run: |
echo "🔍 Running pip-audit dependency scan..."
pip-audit --desc --format json -r project-requirements.txt > pip-audit-report.json || true
if pip-audit --desc -r project-requirements.txt; then
echo "✅ No vulnerabilities found"
else
echo "❌ Vulnerabilities found!"
exit 1
fi
- name: Upload dependency scan reports
uses: actions/upload-artifact@v4
if: always()
with:
name: dependency-scan-reports
path: pip-audit-report.json
retention-days: 30
sast-scan:
name: Static Application Security Testing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Bandit
run: pip install bandit[toml]
- name: Run Bandit SAST (Fail on HIGH/MEDIUM issues)
run: |
echo "🔍 Running Bandit SAST scan..."
# -ll = only report HIGH and MEDIUM severity
# Exit code 1 if issues found
bandit -r cleancloud/ -ll -f json -o bandit-report.json
# Also print human-readable output
bandit -r cleancloud/ -ll
- name: Upload Bandit report
uses: actions/upload-artifact@v4
if: always()
with:
name: bandit-report
path: bandit-report.json
retention-days: 30
secrets-scan:
name: Secrets Scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for comprehensive scan
- name: TruffleHog Secrets Scan - PR
if: github.event_name == 'pull_request'
uses: trufflesecurity/trufflehog@v3.94.3
with:
path: ./
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}
extra_args: --only-verified
- name: TruffleHog Secrets Scan - Push to Main
if: github.event_name == 'push'
uses: trufflesecurity/trufflehog@v3.94.3
with:
path: ./
base: ${{ github.event.before }}
head: ${{ github.event.after }}
extra_args: --only-verified
license-compliance:
name: License Compliance Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[all]"
pip install pip-licenses
- name: Generate license report
run: |
echo "📋 Generating license compliance report..."
pip-licenses --format=json --with-urls --with-description > licenses.json
pip-licenses --format=markdown > licenses.md
echo "## License Summary"
pip-licenses --summary
- name: Check for non-permissive licenses (FAIL on GPL/AGPL)
run: |
echo "🔍 Checking for restrictive licenses..."
# Fail if GPL, AGPL, or unknown licenses found
if pip-licenses | grep -iE "GPL|AGPL|Unknown"; then
echo "❌ Found restrictive or unknown licenses!"
pip-licenses
exit 1
else
echo "✅ All licenses are permissive"
fi
- name: Upload license reports
uses: actions/upload-artifact@v4
if: always()
with:
name: license-reports
path: |
licenses.json
licenses.md
retention-days: 30
codeql:
name: CodeQL Security Analysis
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: python
queries: security-extended
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
security-summary:
name: Security Scan Summary
runs-on: ubuntu-latest
needs: [dependency-scan, sast-scan, secrets-scan, license-compliance, codeql]
if: always()
steps:
- name: Check if all scans passed
run: |
echo "🔒 Security Scan Summary"
echo "========================"
if [ "${{ needs.dependency-scan.result }}" != "success" ]; then
echo "❌ Dependency scan FAILED"
exit 1
fi
if [ "${{ needs.sast-scan.result }}" != "success" ]; then
echo "❌ SAST scan FAILED"
exit 1
fi
if [ "${{ needs.secrets-scan.result }}" != "success" ]; then
echo "❌ Secrets scan FAILED"
exit 1
fi
if [ "${{ needs.license-compliance.result }}" != "success" ]; then
echo "❌ License compliance FAILED"
exit 1
fi
if [ "${{ needs.codeql.result }}" != "success" ]; then
echo "❌ CodeQL analysis FAILED"
exit 1
fi
echo "✅ All security scans passed!"
echo ""
echo "Scans completed:"
echo " ✅ Dependency vulnerabilities (pip-audit)"
echo " ✅ Code security (Bandit SAST)"
echo " ✅ Secrets detection (TruffleHog)"
echo " ✅ License compliance (pip-licenses)"
echo " ✅ Advanced security analysis (CodeQL)"