name: Security Scanning on: schedule: - cron: '0 2 * * *' # Daily at 2 AM UTC workflow_dispatch: push: branches: [ main, develop ] jobs: # Container Security Scanning container-scan: name: Container Security Scan runs-on: ubuntu-latest strategy: matrix: service: - api-gateway - orchestrator - claude-agent - analytics - logging steps: - uses: actions/checkout@v4 - name: Run Trivy scanner uses: aquasecurity/trivy-action@master with: scan-type: 'fs' scan-ref: './services/${{ matrix.service }}' format: 'sarif' output: 'trivy-${{ matrix.service }}.sarif' severity: 'CRITICAL,HIGH' - name: Upload Trivy results to GitHub Security uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-${{ matrix.service }}.sarif' category: 'trivy-${{ matrix.service }}' # SAST - Static Application Security Testing sast-scan: name: SAST Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: javascript, typescript queries: security-and-quality - name: Autobuild uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 - name: Run Semgrep uses: returntocorp/semgrep-action@v1 with: config: >- p/security-audit p/nodejs p/typescript p/mongodb p/jwt # Secret Scanning secret-scan: name: Secret Scanning runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: TruffleHog scan uses: trufflesecurity/trufflehog@main with: path: ./ base: ${{ github.event.repository.default_branch }} head: HEAD extra_args: --debug --only-verified - name: GitLeaks scan uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Dependency Security Audit dependency-audit: name: Dependency Security Audit runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run npm audit run: | find . -name package.json -not -path "*/node_modules/*" -execdir npm audit --audit-level=moderate \; - name: Run OWASP Dependency Check uses: dependency-check/Dependency-Check_Action@main with: project: 'marketing-agent' path: '.' format: 'HTML' args: > --enableRetired --enableExperimental - name: Upload dependency check results uses: actions/upload-artifact@v4 with: name: dependency-check-report path: reports/ retention-days: 30 # Infrastructure Security Scan infrastructure-scan: name: Infrastructure Security Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Checkov scan uses: bridgecrewio/checkov-action@master with: directory: . framework: all output_format: sarif output_file_path: checkov.sarif download_external_modules: true - name: Upload Checkov results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: checkov.sarif category: infrastructure - name: Terraform security scan uses: aquasecurity/tfsec-action@v1.0.0 with: working_directory: ./infrastructure/terraform # API Security Testing api-security-test: name: API Security Testing runs-on: ubuntu-latest if: github.event_name == 'schedule' steps: - uses: actions/checkout@v4 - name: Setup OWASP ZAP run: | docker pull owasp/zap2docker-stable - name: Start application run: | docker-compose -f docker-compose.security.yml up -d ./scripts/wait-for-services.sh - name: Run ZAP API scan run: | docker run -v $(pwd):/zap/wrk/:rw \ -t owasp/zap2docker-stable zap-api-scan.py \ -t http://host.docker.internal:3000/api-docs.json \ -f openapi \ -r zap-api-report.html \ -w zap-api-report.md - name: Upload ZAP results uses: actions/upload-artifact@v4 with: name: zap-api-report path: | zap-api-report.html zap-api-report.md retention-days: 30 # Compliance Checks compliance-check: name: Compliance Checks runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: License compliance check uses: fossa-contrib/fossa-action@v2 with: api-key: ${{ secrets.FOSSA_API_KEY }} run-tests: true - name: GDPR compliance check run: | # Check for PII handling ./scripts/compliance/gdpr-check.sh - name: SOC2 compliance check run: | # Check security controls ./scripts/compliance/soc2-check.sh # Security Report Generation generate-report: name: Generate Security Report runs-on: ubuntu-latest needs: [container-scan, sast-scan, secret-scan, dependency-audit, infrastructure-scan] if: always() steps: - uses: actions/checkout@v4 - name: Download all artifacts uses: actions/download-artifact@v4 with: path: security-reports/ - name: Generate consolidated report run: | python scripts/security/generate-security-report.py \ --input security-reports/ \ --output security-summary.html - name: Upload security summary uses: actions/upload-artifact@v4 with: name: security-summary path: security-summary.html retention-days: 90 - name: Create security issue if critical findings uses: actions/github-script@v7 with: script: | const fs = require('fs'); const report = JSON.parse(fs.readFileSync('security-summary.json', 'utf8')); if (report.critical_findings > 0) { await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: `🚨 ${report.critical_findings} Critical Security Findings`, body: report.summary, labels: ['security', 'critical'] }); }