Certified Jenkins Engineer
Kubernetes and GitOps
Demo DAST and Manual Input
In this guide, we’ll extend our Jenkins pipeline with two new stages:
- A manual approval checkpoint after deploying the app via GitOps (Argo CD sync).
- A Dynamic Application Security Testing (DAST) step using OWASP ZAP.
What Is DAST?
Dynamic Application Security Testing (DAST) probes a live application for vulnerabilities like SQL injection and XSS. Instead of scanning source code (SAST), DAST injects malicious payloads at runtime to uncover weaknesses in a running service.
OWASP Zed Attack Proxy (ZAP)
OWASP ZAP is an open-source, community-driven web application scanner. It supports passive, active, and API scans.
ZAP Scan Modes
Mode | Description |
---|---|
Baseline | Time-boxed passive scan |
Full | AJAX Spider + active + passive scans |
API | Scans OpenAPI/GraphQL/SOAP endpoints (our choice) |
We’ll run the API scan against our service’s OpenAPI definition.
zap-api-scan.py Usage
Install or use the Docker image ghcr.io/zaproxy/zaproxy
to invoke zap-api-scan.py
:
zap-api-scan.py -t <target> -f <format> [options]
Key options:
-t <target> API spec URL/file (OpenAPI, SOAP) or GraphQL endpoint
-f <format> openapi | soap | graphql
-r <report_html> Full HTML report
-w <report_md> Markdown report
-J <report_json> JSON report
-x <report_xml> XML report
-c <config_file> Custom INFO/IGNORE/FAIL rules
-g <gen_file> Generate default config (WARN by default)
-a Include alpha passive scan rules
-d Debug output
-P <port> Proxy listen port
-D <delay> Delay (s) before passive scan
-I Treat default rules as INFO
-l Ignore warnings (post 2.9.0)
For full details, see the OWASP ZAP documentation.
Integrating with Jenkins
Add the following stages to your Jenkinsfile
:
Stage | Purpose | Trigger |
---|---|---|
App Deployed? | Manual approval after Argo CD sync | PR branch |
DAST – OWASP ZAP | Run ZAP API scan on deployed service | After approval |
1. App Deployed? (Manual Approval)
This stage pauses the pipeline until an operator merges your PR and syncs Argo CD.
stage('App Deployed?') {
when {
branch 'PR*'
}
steps {
timeout(time: 1, unit: 'DAYS') {
input message: 'Has the PR been merged and Argo CD synced?',
ok: 'Yes, proceed with DAST'
}
}
}
Note
The input
step blocks the pipeline until a user clicks Proceed or the timeout expires.
2. DAST – OWASP ZAP
Once approved, execute ZAP against your live API:
stage('DAST - OWASP ZAP') {
when {
branch 'PR*'
}
steps {
sh '''
chmod 777 $(pwd)
docker run -v $(pwd):/zap/wrk/:rw \
ghcr.io/zaproxy/zaproxy zap-api-scan.py \
-t http://<K8S_IP>:30000/api/docs/ \
-f openapi \
-r zap_report.html \
-w zap_report.md \
-J zap_report.json \
-x zap_report.xml
'''
}
}
Sample OpenAPI Definition
Our service exposes /api/docs/
with this minimal spec:
{
"openapi": "3.0.0",
"info": { "title": "Solar System API", "version": "1.0" },
"paths": {
"/": {
"get": {
"responses": { "200": { "description": "", "content": { "text/plain": { "schema": { "type": "string", "example": "Example" } } } } }
}
},
"/live": {
"get": {
"responses": { "200": { "description": "", "content": { "text/plain": { "schema": { "type": "string", "example": "Example" } } } } }
}
}
}
}
Running the Pipeline
- Commit your
Jenkinsfile
changes and open a PR. - Jenkins triggers a new build:
- App Deployed? waits for merge and Argo CD sync.
- Merge the PR:
- Sync your app in Argo CD:
kubectl -n solar-system get pods
# Example:
# NAME READY STATUS RESTARTS AGE
# solar-system-5f66cbc859-wdlwp 1/1 Running 0 27s
# solar-system-5f66cbc859-wrs24 1/1 Running 0 21s
- Approve and let the pipeline proceed to the DAST stage. ZAP will scan and generate reports.
Warning
If ZAP detects critical issues or unexpected content types, it exits with a non-zero code, causing the stage (and pipeline) to fail. Adjust your -c
config or handle alerts as needed.
References
- Dynamic Application Security Testing (DAST)
- OWASP ZAP Docs
- Jenkins Pipeline Syntax: input
- GitOps Overview
- Argo CD Docs
Watch Video
Watch video content