Integrates SAST, DAST, and SCA into CI/CD pipelines using Semgrep for SAST, Trivy for SCA and container scanning, OWASP ZAP for DAST, and Gitleaks for secrets detection. Use when setting up automated security scanning in CI/CD, shifting security left, meeting compliance mandates (SOC 2, PCI-DSS, ISO 27001), or gating deployments on critical vulnerabilities.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Integrates SAST, DAST, and SCA into CI/CD pipelines using Semgrep for SAST, Trivy for SCA and container scanning, OWASP ZAP for DAST, and Gitleaks for secrets detection. Use when setting up automated security scanning in CI/CD, shifting security left, meeting compliance mandates (SOC 2, PCI-DSS, ISO 27001), or gating deployments on critical vulnerabilities.
Setting up automated security scanning in a new or existing CI/CD pipeline
Shifting security left by catching vulnerabilities before code reaches production
Meeting compliance requirements (SOC 2, PCI-DSS, ISO 27001) that mandate automated security testing
Integrating SAST, DAST, and SCA together to achieve comprehensive application security coverage
Establishing security gates that block deployments containing critical or high-severity vulnerabilities
Do not use as a replacement for manual penetration testing. Automated scanning catches common vulnerability patterns but cannot replace human-driven security assessments for business logic flaws and complex attack chains.
Prerequisites
CI/CD platform: GitHub Actions, GitLab CI, Jenkins, or Azure DevOps
Container runtime (Docker) for running scanning tools
A staging environment URL for DAST scanning (DAST cannot test static code)
Repository access with permissions to modify CI/CD workflow files
Tool-specific requirements:
Semgrep: free for open-source rulesets (p/security-audit, p/owasp-top-ten)
Trivy: free, no account required
OWASP ZAP: free, Docker image available
Gitleaks: free, no account required
Workflow
Step 1: Add Secrets Detection with Gitleaks
Secrets detection runs first because leaked credentials are the highest-priority finding. Add to .github/workflows/security.yml:
For custom rules, create .semgrep/custom-rules.yml:
rules:-id:no-exec-user-inputpatterns:-pattern:exec($INPUT)-pattern-not:exec("...")message:>
User input passed to exec(). This is a command injection vulnerability.
severity:ERRORlanguages: [python]
metadata:cwe:"CWE-78: OS Command Injection"owasp:"A03:2021 - Injection"-id:no-raw-sql-queriespatterns:-pattern:cursor.execute(f"...")-pattern:cursor.execute("..."+...)message:>
SQL query built with string concatenation or f-strings. Use parameterized queries.
severity:ERRORlanguages: [python]
metadata:cwe:"CWE-89: SQL Injection"owasp:"A03:2021 - Injection"
Step 3: Add SCA Scanning with Trivy
Trivy scans dependencies, container images, IaC files, and generates SBOM:
sca-scan:name:SCA&ContainerScan(Trivy)runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-name:RunTrivyfilesystemscan(dependencies)uses:aquasecurity/trivy-action@0.28.0with:scan-type:'fs'scan-ref:'.'severity:'CRITICAL,HIGH'exit-code:'1'format:'json'output:'trivy-fs-results.json'-name:RunTrivyIaCscan(Terraform,CloudFormation)uses:aquasecurity/trivy-action@0.28.0with:scan-type:'config'scan-ref:'.'severity:'CRITICAL,HIGH'exit-code:'1'format:'json'output:'trivy-iac-results.json'-name:UploadSCAresultsif:always()uses:actions/upload-artifact@v4with:name:trivy-resultspath:trivy-*.jsoncontainer-scan:name:ContainerImageScan(Trivy)runs-on:ubuntu-latestneeds: [sast-scan] # Build image only after SAST passessteps:-uses:actions/checkout@v4-name:BuildDockerimagerun:dockerbuild-tapp:${{github.sha}}.-name:Scancontainerimageuses:aquasecurity/trivy-action@0.28.0with:image-ref:'app:${{ github.sha }}'severity:'CRITICAL,HIGH'exit-code:'1'format:'json'output:'trivy-image-results.json'-name:GenerateSBOMuses:aquasecurity/trivy-action@0.28.0with:image-ref:'app:${{ github.sha }}'format:'cyclonedx'output:'sbom.json'-name:UploadSBOMuses:actions/upload-artifact@v4with:name:sbompath:sbom.json
Step 4: Add DAST Scanning with OWASP ZAP
DAST runs against a deployed staging environment. It is slower than SAST/SCA and should run asynchronously or on a schedule:
dast-scan:name:DAST(OWASPZAP)runs-on:ubuntu-latestneeds: [deploy-staging] # Must run after app is deployed to stagingsteps:-uses:actions/checkout@v4-name:RunZAPBaselineScan(fast,suitableforCI)uses:zaproxy/action-baseline@v0.14.0with:target:${{vars.STAGING_URL}}rules_file_name:'.zap/rules.tsv'cmd_options:'-a -j'# For nightly full scans, use action-full-scan instead:# - name: Run ZAP Full Scan (comprehensive, 30-60 min)# uses: zaproxy/action-full-scan@v0.12.0# with:# target: ${{ vars.STAGING_URL }}
Create .zap/rules.tsv to configure alert thresholds:
10010 IGNORE (Cookie No HttpOnly Flag - acceptable for non-sensitive cookies)
10011 IGNORE (Cookie Without Secure Flag - staging uses HTTP)
90033 WARN (Loosely Scoped Cookie)
10038 FAIL (Content Security Policy Header Not Set)
40012 FAIL (Cross Site Scripting - Reflected)
40014 FAIL (Cross Site Scripting - Persistent)
40018 FAIL (SQL Injection)
90019 FAIL (Server Side Code Injection)
90020 FAIL (Remote OS Command Injection)
Step 5: Aggregate Results and Enforce Security Gates
Create a summary job that aggregates all scan results and enforces pass/fail gates:
security-gate:name:SecurityGateruns-on:ubuntu-latestneeds: [secrets-scan, sast-scan, sca-scan, container-scan]
if:always()steps:-name:Checkscanresultsrun:|
echo "Checking security scan results..."
# Fail the pipeline if any upstream job failedif [[ "${{ needs.secrets-scan.result }}"=="failure" ]];thenecho"BLOCKED: Secrets detected in repository"exit1fiif [[ "${{ needs.sast-scan.result }}"=="failure" ]];thenecho"BLOCKED: SAST found critical/high vulnerabilities"exit1fiif [[ "${{ needs.sca-scan.result }}"=="failure" ]];thenecho"BLOCKED: SCA found critical/high vulnerable dependencies"exit1fiif [[ "${{ needs.container-scan.result }}"=="failure" ]];thenecho"BLOCKED: Container image has critical/high vulnerabilities"exit1fiecho"All security gates passed"
Step 6: Configure Branch Protection Rules
Enforce the security pipeline as a required status check:
GitHub Repository > Settings > Branches > Branch Protection Rules
Branch name pattern: main
Require status checks to pass before merging: Enabled
Required status checks:
- Secrets Detection (Gitleaks)
- SAST (Semgrep)
- SCA & Container Scan (Trivy)
- Security Gate
Require branches to be up to date before merging: Enabled
Step 7: Set Up Developer Feedback Loop
Configure pre-commit hooks so developers catch issues before pushing: