Skip to content
Learni
View all tutorials
Sécurité Applicative

How to Automate Advanced DAST Testing with ZAP in 2026

Lire en français

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

docker-compose.yml
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=secretkey123

This 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

configure_zap.py
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

advanced_scan.py
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

.github/workflows/dast.yml
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 down

This 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

report_analysis.py
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.

How to Automate DAST Tests with ZAP in CI/CD Pipelines (2026) | Learni