Skip to main content

OWASP ZAP component

This component runs an OWASP Zed Attack Proxy Automation Framework plan (zap.yaml) and publishes the generated ZAP reports as GitLab artifacts.

The component runs the supplied scan plan, removes any existing ZAP report jobs, and appends standard JSON, HTML, Markdown, and PDF report jobs automatically. After the plan finishes, it converts the traditional JSON report into a GitLab JUnit test report so findings are visible in the pipeline test report.

The bundled scanner image uses ZAP's minimal upstream bare runtime, plus Python and PyYAML for plan normalization. It intentionally excludes the desktop and browser packages from the full ZAP image because the component runs Automation Framework plans in CI.

Usage​

Pick the smallest plan that matches the target. Each example uses environment variables so the same plan works for review apps, staging, and local targets.

Use caseStart withRequired variable
Crawl a web applicationcrawl.yamlZAP_TARGET_URL
Crawl an API behind OAuthoauth-crawl.yamlZAP_TARGET_URL, ZAP_OAUTH_ACCESS_TOKEN
Import an OpenAPI definitionopenapi.yamlZAP_TARGET_URL, ZAP_OPENAPI_URL
Test one REST endpointrest-endpoint.yamlZAP_TARGET_URL

Create a ZAP Automation Framework plan in your project, for example zap.yaml:

env:
contexts:
- name: application
urls:
- https://www.example.com/
parameters:
failOnError: true
failOnWarning: false
progressToStdout: true
jobs:
- type: spider
parameters:
context: application
url: https://www.example.com/
maxDuration: 5
- type: passiveScan-wait
parameters:
maxDuration: 5

Then include the component and pass the plan path:

include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/common@stable
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/zap@stable
inputs:
name: application
plan: zap.yaml
stage: test
needs: []

The component exports ZAP_REPORT_DIR and ZAP_REPORT_BASENAME before running ZAP and appends report jobs that create the standard artifact names:

  • ${ZAP_REPORT_BASENAME}.json
  • ${ZAP_REPORT_BASENAME}.html
  • ${ZAP_REPORT_BASENAME}.md
  • ${ZAP_REPORT_BASENAME}.pdf

The JSON report uses the traditional-json template and is converted into ${ZAP_REPORT_BASENAME}-junit.xml. Informational findings (riskcode: 0) remain available in the original ZAP artifacts but are omitted from the GitLab JUnit report.

The JUnit report contains one failing or passing test case for each non-informational grouped ZAP finding. Test names use <alert name> <risk>, suites use OWASP ZAP <plugin ID>, and the formatted system output for each test case contains its risk, plugin ID, plain-text description, affected instances, solution, and references. risk controls the minimum ZAP risk level that fails a test case and defaults to high; lower non-informational risks are included as passing test cases. The original ZAP artifacts retain the complete scanner output.

Standalone scans use the default environment-action: verify, so GitLab treats the job as a scan instead of a deployment that creates a new environment. Use environment-action: start only when the ZAP job should create or own a GitLab environment.

Web application crawl​

Use a traditional spider followed by passiveScan-wait for a server-rendered application whose routes are reachable through links. Set ZAP_TARGET_URL in a dotenv artifact from the deployment job or as a CI/CD variable. The crawl.yaml example is ready to use with the component configuration above.

Traditional spider options are documented in the ZAP spider Automation Framework job. The bundled ZAP image intentionally has no browser, so use a browser-enabled ZAP image and the spiderAjax job for JavaScript-only navigation.

OAuth-protected application​

Obtain a short-lived access token in a dedicated CI job and expose it as the masked ZAP_OAUTH_ACCESS_TOKEN variable. The oauth-crawl.yaml plan uses ZAP's replacer job to add Authorization: Bearer ... to every scan request. Do not commit access tokens to a plan or print them in job logs.

jobs:
- type: replacer
parameters:
deleteAllRules: false
rules:
- description: OAuth access token
matchType: req_header
matchString: Authorization
replacementString: Bearer ${ZAP_OAUTH_ACCESS_TOKEN}

This pattern is appropriate when the OAuth provider can issue a machine token. Interactive authorization-code and multi-factor login flows need ZAP browser-based authentication and therefore a browser-enabled scanner image.

OpenAPI scan​

Use the openapi job when a service publishes a definition. The openapi.yaml plan imports ZAP_OPENAPI_URL, rewrites its server URL to ZAP_TARGET_URL, and passively scans the generated requests. A repository-local definition can use apiFile instead; relative file paths are normalized by this component.

See the ZAP OpenAPI Automation Framework reference for import limits, authenticated users, and target URL behavior.

Single REST endpoint​

Use a requestor job when a focused smoke test is more useful than crawling. The rest-endpoint.yaml example sends GET ${ZAP_TARGET_URL}/api/items, asserts HTTP 200, and then waits for passive analysis. Copy the request entry for additional methods and request bodies. See the ZAP requestor job reference for the complete request schema.

Runnable .NET example​

container/zap-example contains a small ASP.NET Core application with a crawlable page, REST endpoint, OpenAPI document, optional OAuth bearer-token validation, and OpenTelemetry logs written to standard output. Its multi-stage Containerfile uses Red Hat Hardened .NET images and runs the result as a non-root user.

Build the sample with the container component:

include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/common@stable
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/container@stable
inputs:
name: zap-example
path: container/zap-example

Deploy it with the included Helm chart and scan the service through an ingress:

helm upgrade --install zap-example charts/zap-example \
--set image.repository="$CI_REGISTRY_IMAGE/zap-example" \
--set image.tag="$CI_COMMIT_SHA" \
--set ingress.enabled=true \
--set ingress.host="zap-${CI_COMMIT_REF_SLUG}.example.com"

Set oauth.authority and oauth.audience on the chart to enable bearer-token validation. The sample follows the official ASP.NET Core minimal API authentication guidance and OpenTelemetry .NET logging guidance.

Review app scan​

When scanning a review app, include the review component and make the ZAP job depend on review:start. If the review start script writes values such as ZAP_TARGET_URL to review.env, the plan can use them via Automation Framework variable expansion.

include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/review@stable
inputs:
review-start-script: scripts/start-review.sh
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/zap@stable
inputs:
name: review
plan: zap.yaml
needs:
- job: review:start
artifacts: true
environment-action: verify

Example plan fragment:

env:
contexts:
- name: review
urls:
- ${ZAP_TARGET_URL}
jobs:
- type: spider
parameters:
context: review
url: ${ZAP_TARGET_URL}

Inputs​

NameRequiredDescription
namenoName for the ZAP job and generated report files.
planyesPath to the ZAP Automation Framework plan file (zap.yaml) to execute.
stagenoPipeline stage for the scan job.
rulesnoRules that control when the scan job runs.
needsnoJobs that the scan job depends on.
allow-failurenoLet the pipeline continue if the plan fails.
fail-on-warnnoTreat warning-level ZAP findings as a failed job after the plan completes.
risknoMinimum ZAP risk that fails JUnit test cases: informational, low, medium, or high (default). Lower risk findings are reported as passing tests.
environmentnoReview environment name used when verifying a review app.
environment-identifiernoReview environment identifier used by the review component.
environment-actionnoGitLab environment action for the scan job. Defaults to verify; use start only when the scan job should create or own an environment.
tagsnoRunner tags for the scan job.

Inputs​

NameDescriptionDefaultType
------------
allow-failureShould the pipeline continue if the ZAP plan fails?falseboolean
environmentReview environment name used when verifying a review app.teststring
environment-actionGitLab environment action for the ZAP job. Use verify when the job depends on an existing review environment.verifystring
environment-identifierReview environment identifier used by the review component./zap-$CI_PROJECT_NAME-$CI_COMMIT_SHORT_SHAstring
fail-on-warnShould warning-level ZAP findings fail the job after the plan completes?falseboolean
nameName for the ZAP job and report files.$CI_PROJECT_NAMEstring
needsThe jobs that this job depends on.[]array
planPath to the OWASP ZAP Automation Framework plan file (zap.yaml) to execute.string
riskMinimum ZAP risk level that fails a JUnit testcase. Lower risk findings are reported as passing testcases.highstring
rulesThe rules that control when the ZAP job runs.[{"if":"$CI_PIPELINE_SOURCE == \"schedule\"","when":"never"},{"if":"$CI_PIPELINE_SOURCE == \"merge_request_event\"","when":"on_success"},{"when":"on_success"}]array
stageThe pipeline stage that the job belongs to.teststring
tagsThe runners that this job depends on.[]array