47 / 70 · 07 Security Testing for AI Apps · SAST, DAST, and SCA in CI: Shift-Left Security Pipeline← prev⊞ allnext →☰ Read as one page
8.3Complete CI Security Pipeline
# .github/workflows/security.yml
name: Security Checks
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep SAST scan
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/python
p/typescript
p/secrets
p/ai-security
generateSarif: true
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Snyk dependency scan
uses: snyk/actions/python@master
with:
args: --severity-threshold=high
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect secrets
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
dast:
runs-on: ubuntu-latest
needs: [sast, sca] # only run DAST if static checks pass
steps:
- uses: actions/checkout@v4
- name: Deploy to ephemeral environment
run: ./scripts/deploy-ephemeral.sh
- name: OWASP ZAP full scan
uses: zaproxy/action-full-scan@v0.10.0
with:
target: ${{ env.EPHEMERAL_URL }}
rules_file_name: zap-rules.tsv
cmd_options: '-a -j'
- name: Upload ZAP report
uses: actions/upload-artifact@v4
with:
name: zap-report
path: report_html.html
container-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t app:${{ github.sha }} .
- name: Trivy container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: app:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: 'CRITICAL,HIGH'
- name: Upload Trivy SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif