Introduction
Dynamic Application Security Testing (DAST) identifies vulnerabilities by analyzing a running application. Unlike SAST, DAST interacts with the interface like a real attacker. In 2026, advanced automation via OWASP ZAP in CI/CD pipelines has become essential for DevSecOps teams. This tutorial guides you step-by-step through professional dynamic scan integration, complex context management, and automated result analysis.
Prerequisites
- Docker and Docker Compose installed
- Advanced knowledge of CI/CD (GitHub Actions or GitLab CI)
- OWASP ZAP 2.15+ and Python 3.11+
- A web application accessible locally or via URL
Installing and Launching ZAP
version: '3.8'
services:
zap:
image: owasp/zap2docker-stable
volumes:
- ./zap:/zap/wrk
command: zap.sh -daemon -host 0.0.0.0 -port 8080 -config api.key=secretkey123This compose file starts ZAP in daemon mode with a secure API key. The shared volume allows storage of reports and persistent contexts.
Advanced Context Configuration
import requests
ZAP_URL = 'http://localhost:8080'
API_KEY = 'secretkey123'
def create_context():
r = requests.get(f'{ZAP_URL}/JSON/context/action/newContext', params={'apikey': API_KEY, 'contextName': 'ProductionApp'})
print(r.json())
create_context()This Python script creates a dedicated named context for the target application. It isolates rules, exclusions, and authentication settings for precise, reproducible scans.
Complete Scan Script with Authentication
import requests
import time
ZAP_URL = 'http://localhost:8080'
API_KEY = 'secretkey123'
TARGET = 'https://app.example.com'
requests.get(f'{ZAP_URL}/JSON/spider/action/scan', params={'apikey': API_KEY, 'url': TARGET})
time.sleep(30)
requests.get(f'{ZAP_URL}/JSON/ascan/action/scan', params={'apikey': API_KEY, 'url': TARGET, 'contextName': 'ProductionApp'})
print('Scan launched successfully')This script triggers a spider followed by an active scan using the created context. It includes a pause to let the spider finish before starting the active scan.
GitHub Actions Integration
name: DAST Scan
on: [push]
jobs:
dast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run ZAP Scan
run: |
docker compose up -d
python advanced_scan.py
docker compose downThis workflow automatically triggers a DAST scan on every push. It uses docker-compose and the Python script to run tests reproducibly in CI.
Results Analysis and Export
import requests
ZAP_URL = 'http://localhost:8080'
API_KEY = 'secretkey123'
r = requests.get(f'{ZAP_URL}/JSON/core/other/jsonreport', params={'apikey': API_KEY})
with open('zap-report.json', 'w') as f:
f.write(r.text)
print('Report exported')This script retrieves the full JSON report and saves it. It can then be analyzed to block the pipeline if critical vulnerabilities are found.
Best Practices
- Always use contexts and exclusion rules to avoid false positives
- Run DAST scans in parallel with functional tests
- Version ZAP contexts in your Git repository
- Define severity thresholds to automatically block deployments
- Execute full nightly scans in addition to quick CI scans
Common Mistakes to Avoid
- Forgetting to configure authentication in the ZAP context
- Running scans without exclusions on production environments
- Ignoring false positives and overwhelming teams with tickets
- Failing to version configuration and reporting scripts
Going Further
Explore our advanced training on application security and DevSecOps automation at Learni Group.