Code builds, and three minutes later the pipeline fails because of a false positive. The developer gets frustrated, disables the step, and security becomes just paperwork again. We see this in nearly every project that lands on our desk: SAST and DAST are enabled, but nobody configured them to work with the team, not against it.
We, at Meteora Web, have been working on DevSecOps pipelines for years. We come from accounting, bookkeeping, and retail: we know that a production block costs more than a postponed vulnerability. So when we talk about Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) in the pipeline, we think in terms of code quality, delivery speed, and the cost of false positives. Not checkbox certifications.
This guide is for teams who already have a pipeline (GitHub Actions, GitLab CI, Jenkins) and want to add security without turning CI into a bottleneck. Let's get concrete: tools, configurations, result management, and automation.
Why integrate SAST and DAST into your development pipeline?
Because a vulnerability found in production costs 6–7 times more than one caught at commit time. And that's not just money: it's exposed data, lost customers, reputational damage. With SAST, you analyze source code without running it: find SQL Injection, XSS, hardcoded secrets, vulnerable dependencies. With DAST, you simulate external attacks on a running application: find misconfigurations, authentication errors, exposed logic.
Sponsored Protocol
We use both in the pipeline because they complement each other. SAST alone can't see runtime errors. DAST alone can't see dead code or outdated libraries. Together they cover ~80% of common vulnerabilities. The rest we leave to periodic penetration tests — but those don't belong in CI.
What you risk without static and dynamic analysis in the pipeline
- Code with vulnerabilities goes straight to production, never reviewed for security.
- Dependencies with known CVEs stay untouched for months.
- Hardcoded credentials land on GitHub and get scanned by malicious bots.
- Configuration errors (open CORS, missing HTTPS redirect, missing security headers) go live.
Which SAST tools to choose for your stack?
Choice depends on language and budget. We use Semgrep for multi-language projects (Python, PHP, JavaScript, TypeScript, Java) because it's fast, has customizable rules, and integrates into GitHub Actions in 5 minutes. For PHP/Laravel, PHPStan with security extensions or Psalm work well. For Java/Kotlin, SpotBugs with Find Security Bugs. For containers, Trivy scans Docker images for CVEs.
Sponsored Protocol
Practical advice: don't rely on a single commercial "all-in-one" tool if your stack is heterogeneous. Sometimes combining 2–3 open-source tools gives better coverage at zero license cost.
Concrete example: SAST with Semgrep in GitHub Actions
name: SAST
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep --config=auto --error --output=semgrep-results.sarif .
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep-results.sarif
category: semgrep
This configuration runs Semgrep with automatic rules on every push and PR. If it finds critical vulnerabilities (error-level), it blocks the build. Results are uploaded to the GitHub Security Tab. Zero license cost, zero complexity.
How to automate DAST in builds without blocking production?
DAST needs a running application. In the pipeline you have two approaches: DAST on a staging environment (safer, but requires a preliminary deploy) or DAST on a temporary container (faster, but less representative). We prefer the first: deploy to staging, then scan with OWASP ZAP in "baseline" or "full" mode.
Sponsored Protocol
The critical point: timing. A full DAST scan can take 20–30 minutes. It doesn't make sense to run it on every commit. We schedule it: full scan on merge to main, baseline scan on every PR. The baseline checks only security headers, HTTPS presence, and the most obvious vulnerabilities.
Example: DAST with OWASP ZAP in GitHub Actions
name: DAST Baseline
on:
pull_request:
branches: [main]
jobs:
zap_scan:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Deploy staging (if not already up)
run: |
docker compose -f docker-compose.staging.yml up -d
- name: ZAP Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'http://localhost:8080'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-I -c config/zap.conf'
- name: Upload report
uses: actions/upload-artifact@v4
with:
name: zap-report
path: report.html
Note: the .zap/rules.tsv file allows ignoring known false positives. We keep it in the repo, updated weekly by the team. Without this filter, ZAP blocks the build for trivial warnings and devs disable everything.
Sponsored Protocol
SAST vs DAST: where do false positives come from and how to manage them?
False positives are the number one enemy of security adoption in the pipeline. A team receiving 50 fake alerts per day learns to ignore them. We've seen projects where SAST flagged "SQL Injection" on ORM-built queries — 100% false positives. The solution? Rule tuning.
For Semgrep, we create custom rules for specific stacks. For ZAP, we maintain an exclusion list (rules disabled for admin pages, or for endpoints that require authentication). And most importantly: we never block the build on a warning. Only on confirmed errors. Warnings go to a report, analyzed in the technical backlog.
Practical strategy for handling false positives
- Calibrate each SAST/DAST tool for 2 weeks before enabling blocking mode.
- Use a versioned configuration file (e.g.
.semgrepignore,.zap/rules.tsv). - Assign an owner for every alert: who triages it, with what priority.
- Automate triage with GitHub/GitLab labels: if the same alert appears 3 times and is closed as false positive, silence it.
How to measure the effectiveness of SAST and DAST in the pipeline?
You don't need a complex dashboard. We track three metrics:
- Pre-production detection rate: how many vulnerabilities are found before merging to main.
- Mean time to remediation: from alert creation to resolution (or silencing).
- False positive rate: if it exceeds 30%, the tool is misconfigured.
If the pre-production detection rate is below 70% or the mean time to remediation is above 7 days, security isn't part of the workflow. You need a policy review and more team training.
Sponsored Protocol
What to do next
- Install Semgrep (or the SAST tool for your main language) and integrate it into GitHub Actions or GitLab CI. Start with default rules, don't block yet.
- Set up OWASP ZAP Baseline on a staging environment. Leave it in "report-only" mode for a week, collect false positives, and create the exclusion rule file.
- Define a triage process: every alert assigned to a developer, with a maximum of 3 working days for analysis.
- After two weeks of calibration, enable blocking only for critical errors (e.g., confirmed RCE, SQL Injection, secret leaks).
- If you don't yet have a DevSecOps pipeline, read our pillar guide on Cloud Security and DevSecOps.
We at Meteora Web do this every day. Integrating SAST and DAST is not an IT project — it's a cultural change. But if configured well, it becomes invisible, and the team doesn't even notice they're doing security.