DAST & the scan pipeline
Test the running app; wire it all together.
Every scanner so far is static — it reads code, dependencies, or an image at rest. Dynamic Application Security Testing (DAST) is the opposite: it deploys the running application to a test environment and attacks it like an outsider would, probing live endpoints for issues that only appear at runtime — authentication flaws, injection reflected in responses, misconfigured headers, exposed admin paths. OWASP ZAP is the common engine, and GitLab wraps it in a template.
include:- template: DAST.gitlab-ci.ymldast:variables:DAST_WEBSITE: https://staging.acme.internal # a deployed test instancestage: dast# runs after deploy-to-staging; probes the live app, not the source
DAST needs a running target — and time
Because it attacks a live app, DAST runs late (after a deploy to staging) and is slower than static scans — a full active scan can take many minutes. So it usually does not gate every merge request; the common pattern is a fast passive/baseline scan on MRs and a full active scan nightly or before a release. It complements static analysis rather than replacing it: SAST sees the code DAST cannot reach, DAST sees the runtime behavior SAST cannot predict.
Wiring the whole scan pipeline together
Put the pieces in order and you have a defense-in-depth pipeline: SAST, secret detection, and SCA run early on the source and dependencies; the image scan runs after build and gates the push; DAST runs after the staging deploy. Each stage catches what the others miss, each reports fully and gates on the actionable subset, and together they mean a change is checked five ways before it can reach production.
stages: [test, build, scan-image, deploy-staging, dast, deploy-prod]# test: sast, secret-detection, dependency-scanning (source + deps)# scan-image: trivy image (gate the push)# dast: probe the staging deploy# deploy-prod: manual, protected environment (next section)