name: ZAP Security Scan

on:
  workflow_dispatch:
    inputs:
      url:
        description: "URL to scan (default is the GitHub Pages site)"
        required: false
        default: "https://hack23.github.io/game/"
      scan_type:
        description: "Scan type: 'baseline' (fast, passive) or 'full' (active, slow)"
        required: false
        # Default to the safe/passive scan; full active scan must be opted into.
        default: "baseline"
        type: choice
        options:
          - baseline
          - full
  # Run a baseline scan against the public site every Monday at 06:00 UTC.
  # This is a low-traffic window that gives us continuous DAST coverage at the
  # start of each working week without manual dispatch and without competing
  # with weekday CI load.
  schedule:
    - cron: "0 6 * * 1"

# Restrict permissions to minimum required
permissions:
  contents: read
  issues: write # Required if you want ZAP to create GitHub issues for vulnerabilities

jobs:
  zap_baseline_scan:
    name: ZAP Baseline Scan (passive)
    # Baseline runs on schedule, on workflow_dispatch when not explicitly "full",
    # and is the safe default. It performs only passive checks (≈1-3 minutes).
    if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.scan_type != 'full')
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
        with:
          egress-policy: audit

      - name: Checkout repository (for rules file)
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: ZAP Baseline Scan
        uses: zaproxy/action-baseline@7c4deb10e6261301961c86d65d54a516394f9aed # v0.14.0
        with:
          token: ${{ github.token }}
          # Pin to immutable digest of ghcr.io/zaproxy/zaproxy:stable so scheduled
          # scans are reproducible week-to-week and not subject to silent base-image
          # updates. Update this digest in lockstep with ZAP releases.
          docker_name: "ghcr.io/zaproxy/zaproxy:stable@sha256:8770b23f9e8b49038f413cb2b10c58c901e5b6717be221a22b1bcab5c9771b8a"
          target: ${{ github.event.inputs.url || 'https://hack23.github.io/game/' }}
          rules_file_name: ".zap/rules.tsv"
          allow_issue_writing: true
          fail_action: false
          artifact_name: zap-baseline-report

  zap_full_scan:
    name: ZAP Full Scan (active)
    # Full scan only runs when explicitly requested via workflow_dispatch with
    # scan_type=full. It is significantly slower (≥30 minutes) and performs
    # active attacks, so we never run it on schedule.
    if: github.event_name == 'workflow_dispatch' && github.event.inputs.scan_type == 'full'
    runs-on: ubuntu-latest
    timeout-minutes: 120
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
        with:
          egress-policy: audit

      - name: Checkout repository (for rules file)
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: ZAP Full Scan
        uses: zaproxy/action-full-scan@3c58388149901b9a03b7718852c5ba889646c27c # v0.13.0
        with:
          token: ${{ github.token }}
          # Pin to immutable digest of ghcr.io/zaproxy/zaproxy:stable for
          # reproducibility of full active scans. Keep in sync with the digest
          # used by the baseline job above.
          docker_name: "ghcr.io/zaproxy/zaproxy:stable@sha256:8770b23f9e8b49038f413cb2b10c58c901e5b6717be221a22b1bcab5c9771b8a"
          target: ${{ github.event.inputs.url }}
          rules_file_name: ".zap/rules.tsv"
          allow_issue_writing: true
          fail_action: false
          artifact_name: zap-full-report
