Skip to content

actions-scanner-zap-from-config.yml

name: ZAP DAST from Config (Composite Actions)

# Reusable example: parse a ``zap-config.yml`` into a scan matrix and
# run scanner-zap once per entry. ``parse-zap-config`` produces a
# matrix with target/scan metadata; we forward the inputs scanner-zap
# accepts on its current contract:
#
#   scan_name, scan_mode, scan_type, target_url, app_image_ref,
#   app_ports, app_env, startup_timeout, fail_on_severity,
#   post_pr_comment, enable_code_security, job_id, python_version
#
# Earlier revisions of this example also forwarded api_spec,
# healthcheck_url, app_build_context, app_dockerfile, app_image_tag,
# compose_file, compose_build, registry_username, registry_password,
# max_duration_minutes, rules_file_name, cmd_options, allow_failure
# — those inputs no longer exist on scanner-zap. If your DAST flow
# depended on them, build / pull / health-check / log-in to the
# image in a previous step, then point scanner-zap at the running
# target via target_url or app_image_ref + app_ports.

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:
    inputs:
      config_file:
        description: 'Path to ZAP config file'
        required: false
        default: 'examples/configs/zap-config.example.yml'
        type: string

permissions:
  contents: read
  actions: read
  pull-requests: write

jobs:
  parse-config:
    name: Parse ZAP Config
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.parse.outputs.matrix }}
      has_scans: ${{ steps.parse.outputs.has_scans }}
      scan_count: ${{ steps.parse.outputs.total_scan_count }}
      post_pr_comment: ${{ steps.parse.outputs.post_pr_comment }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Parse ZAP config
        id: parse
        uses: huntridge-labs/argus/.github/actions/parse-zap-config@1.1.0
        with:
          config_file: ${{ inputs.config_file || 'examples/configs/zap-config.example.yml' }}

      - name: Display parsed config
        run: |
          echo "📋 Config file: ${{ inputs.config_file }}"
          echo "📊 Scan count: ${{ steps.parse.outputs.total_scan_count }}"
          echo "💬 PR comment: ${{ steps.parse.outputs.post_pr_comment }}"
          echo ""
          echo "🔍 Matrix JSON:"
          echo '${{ steps.parse.outputs.matrix }}' | jq '.'

  zap-scan:
    name: ZAP ${{ matrix.name }}
    runs-on: ubuntu-latest
    needs: parse-config
    if: needs.parse-config.outputs.has_scans == 'true'
    timeout-minutes: 60
    continue-on-error: true
    strategy:
      fail-fast: false
      max-parallel: 3
      matrix: ${{ fromJson(needs.parse-config.outputs.matrix) }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Run ZAP scanner
        uses: huntridge-labs/argus/.github/actions/scanner-zap@1.1.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          scan_name: ${{ matrix.name }}
          scan_type: ${{ matrix.scan_type }}
          target_url: ${{ matrix.target_url }}
          app_image_ref: ${{ matrix.image }}
          app_ports: ${{ matrix.ports }}
          fail_on_severity: ${{ matrix.fail_on_severity }}
          post_pr_comment: ${{ matrix.post_pr_comment }}

  summary:
    name: ZAP Summary
    runs-on: ubuntu-latest
    needs: [parse-config, zap-scan]
    if: always()
    steps:
      - name: Generate ZAP Summary
        uses: huntridge-labs/argus/.github/actions/scanner-zap-summary@1.1.0
        id: summary
        with:
          post_pr_comment: ${{ needs.parse-config.outputs.post_pr_comment || 'true' }}

      - name: Check for critical findings
        if: steps.summary.outputs.total_critical > 0 || steps.summary.outputs.total_high > 0
        run: |
          echo "::warning::Found security findings - Critical: ${{ steps.summary.outputs.total_critical }}, High: ${{ steps.summary.outputs.total_high }}"