Skip to content

Incremental Scanning and Configuration Overrides

Focus Security Testing on Code Changes

Use incremental scanning to test the API endpoints, web pages, and user flows affected by a pull request or merge request. Your pipeline selects the scope, and Escape runs security tests within that configured scope.

Escape's Incremental Scanning Architecture

Use configuration overrides to narrow API Testing or WebApp Testing scope to the paths your pipeline identifies as affected by code changes.

You choose what to test. Map your Git diff to affected routes, endpoints, or pages in your CI/CD job, then pass that scope to Escape through configuration overrides. A scan started without overrides uses the profile's normal scope.

How Incremental Scanning Works:

Start a scan via the Escape CLI or Public API with configuration overrides to select endpoints, URL patterns, and testing parameters for that run.

Architecture By Design:

Escape's scanning engine applies scope rules at the configuration level. Incremental scans use the profile's security tests and reporting with the overrides you supply.

CI/CD Integration Workflow

Integrate incremental scanning into merge request or pull request automation. Your pipeline detects changes and maps them to scan scope in steps 1 and 2. Escape receives the resulting overrides when the scan starts.

1. Code Change Detection

Your CI/CD automation analyzes the code diff to identify modified files, changed API routes, or affected web pages. Choose an approach that fits your application:

  • Git Diff Analysis: Parsing commit diffs to identify changed backend routes, API endpoint definitions, or frontend page components
  • Framework-Specific Detection: Using framework metadata (OpenAPI specifications, route registries, component mappings) to map code changes to runtime paths
  • Static Analysis: Analyzing import graphs and dependency chains to identify indirectly affected endpoints

2. Scan Scope Calculation

Translate the affected application paths into Escape configuration overrides in your pipeline:

  • API Testing: Specific REST endpoints, GraphQL operations, or API route patterns
  • WebApp Testing: URL patterns for affected pages, navigation flows through modified components

3. Incremental Scan Execution

The CI/CD pipeline invokes Escape with the calculated scope. Escape applies the supplied overrides to the scan. Review the findings before merging.

4. Merge Decision Gating

Use --watch to wait for a terminal scan state. Then use a quality-gate script to require a FINISHED scan and evaluate open findings before allowing a merge. The script controls the build's pass or fail decision.

Configuration Override Capabilities

Pass configuration overrides with the CLI's -c or --override flag, or the Public API's configurationOverride parameter. Overrides control both scan behavior and scope.

WebApp Testing Scope

Use Case: A merge request modifies the checkout flow, affecting the cart, shipping, and payment pages. Testing is focused on these specific user interface paths.

Implementation:

escape-cli scans start [profile-id] -c '{
  "frontend_dast": {
    "scope": {
      "crawling": {
        "allowlist": [
          { "type": "web_page_url", "value": "https://shop.example.com/cart", "operation": "starts_with" },
          { "type": "web_page_url", "value": "https://shop.example.com/checkout/shipping", "operation": "starts_with" },
          { "type": "web_page_url", "value": "https://shop.example.com/checkout/payment", "operation": "starts_with" }
        ]
      }
    },
    "hotstart": [
      "https://shop.example.com/cart",
      "https://shop.example.com/checkout/shipping",
      "https://shop.example.com/checkout/payment"
    ]
  }
}'

Configuration Parameters:

  • scope.crawling.allowlist: Defines the URL scope boundary using structured rules. Each rule specifies a type (for example web_page_url, domain), a value to match, and an optional operation (equals, starts_with, contains, regex, wildcard). The browser-based crawler won't navigate beyond these patterns, preventing exploration of unchanged application areas.
  • hotstart: Specifies explicit entry points for crawling. The scanner will navigate directly to these URLs and begin exploration from each, rather than discovering them through link traversal from the application root.

REST API Testing Scope

Use Case: A pull request modifies the /api/users and /api/orders REST endpoints. Testing is constrained to these specific paths.

Implementation:

Use an allowlist to select the affected paths. Set extend_global_scope to false to use this scan's allowlist independently of the global allowlist. The global blocklist still applies.

escape-cli scans start [profile-id] -c '{
  "rest_api_dast": {
    "scope": {
      "extend_global_scope": false,
      "allowlist": [
        { "type": "rest_api_path", "value": "/api/users", "operation": "starts_with" },
        { "type": "rest_api_path", "value": "/api/orders", "operation": "starts_with" }
      ]
    }
  }
}'

Scope Rules:

Use rest_api_path rules for REST API DAST targets. Each rule has a type, value, and optional operation (equals, starts_with, ends_with, contains, regex, wildcard). Add method (for example GET or POST) to select an HTTP method. REST API DAST evaluates these targets by path and method; the domain field and URL-based rules don't affect path-only targets. See API Testing Scope for details.

GraphQL API Scope

Use Case: Changes to the GraphQL schema introduce new fields on the User and Order types. Testing is constrained to these specific types and their operations.

Implementation:

Use an allowlist to select the affected operations. Set extend_global_scope to false to use this scan's allowlist independently of the global allowlist. The global blocklist still applies.

escape-cli scans start [profile-id] -c '{
  "graphql_api_dast": {
    "scope": {
      "extend_global_scope": false,
      "allowlist": [
        { "type": "graphql_operation", "value": "user", "operation": "contains" },
        { "type": "graphql_operation", "value": "order", "operation": "contains" }
      ]
    }
  }
}'

Behavioral Override Examples

Configuration overrides also control testing behavior for specific CI/CD contexts. Use fields from the scanner configuration schema.

Read-Only vs. Read-Write Testing

Use Case: The production scan profile is configured in read-only mode to prevent data modification. For staging environment PR validation, write operations should be tested.

Implementation:

escape-cli scans start [profile-id] -c '{
  "mode": "read_write"
}'

This override enables POST, PUT, PATCH, and DELETE operations for the duration of the scan, allowing comprehensive testing of state-modifying endpoints. The mode field accepts "read_only" or "read_write".

Authentication Override

Use Case: CI uses a different authentication header from the profile's normal configuration.

Build JSON with jq so the shell passes the secret's value. The CLI doesn't interpolate environment variable references inside JSON:

OVERRIDE=$(jq -nc --arg token "$CI_ACCESS_TOKEN" '{
  authentication: {
    users: [{name: "ci_user", type: "headers", headers: {Authorization: ("Bearer " + $token)}}]
  }
}')
escape-cli scans start <profile-id> -c "$OVERRIDE"

Security Test Selection

Use Case: A specific pull request modifies SQL query construction. Testing should emphasize SQL injection and related database security tests.

Implementation:

escape-cli scans start [profile-id] -c '{
  "security_tests": {
    "sql": {
      "skip": false
    },
    "nosql": {
      "skip": false
    }
  }
}'

This configuration ensures that database-related security tests are executed even if disabled in the base profile, while other tests follow the profile's default configuration.

Real-World Integration Examples

GitHub Actions Integration

Example workflow shape for incremental scanning on pull requests. The Detect Changed API Paths step is a placeholder: Replace it with diff-to-path mapping for your stack.

name: Incremental Security Scan
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Full history for diff analysis

      - name: Detect Changed API Paths
        id: detect-changes
        run: |
          # Extract changed files from the PR
          CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)

          # Parse API route files and extract affected paths
          # (Framework-specific logic would be implemented here)
          AFFECTED_RULES='[{"type":"rest_api_path","value":"/api/users","operation":"starts_with"},{"type":"rest_api_path","value":"/api/orders","operation":"starts_with"}]'

          echo "rules=$AFFECTED_RULES" >> $GITHUB_OUTPUT

      - name: Install Escape CLI
        run: curl -sf https://raw.githubusercontent.com/Escape-Technologies/cli/refs/heads/main/scripts/install.sh | sudo bash

      - name: Run Incremental Scan
        env:
          ESCAPE_API_KEY: ${{ secrets.ESCAPE_API_KEY }}
          ESCAPE_PROFILE_ID: ${{ secrets.ESCAPE_PROFILE_ID }}
          AFFECTED_RULES: ${{ steps.detect-changes.outputs.rules }}
        run: |
          OVERRIDE=$(jq -nc --argjson rules "$AFFECTED_RULES" '{rest_api_dast: {scope: {extend_global_scope: false, allowlist: $rules}}}')
          escape-cli scans start "$ESCAPE_PROFILE_ID" -c "$OVERRIDE" --watch

GitLab CI Integration

Example pipeline for incremental WebApp Testing on merge requests. Map paths from git diff to application URLs in your pipeline, then pass the resulting JSON to Escape with -c.

incremental_security_scan:
  stage: security
  image:
    name: alpine:3.20
    entrypoint: ['']
  before_script:
    - apk add --no-cache bash ca-certificates curl git jq
    - curl -sf https://raw.githubusercontent.com/Escape-Technologies/cli/refs/heads/main/scripts/install.sh | bash
  script:
    # Analyze merge request diff to identify affected pages
    - |
      AFFECTED_PAGES=$(git diff $CI_MERGE_REQUEST_DIFF_BASE_SHA...HEAD --name-only | \
        grep "^frontend/" | \
        sed 's|^frontend/pages/|https://app.example.com/|' | \
        jq -R -s -c 'split("\n")[:-1]')

    # Build scope rules and hotstart from affected pages
    - |
      SCOPE_RULES=$(echo "$AFFECTED_PAGES" | jq -c '[.[] | {"type":"web_page_url","value":.,"operation":"starts_with"}]')

    # Execute incremental WebApp scan
    - |
      escape-cli scans start $ESCAPE_PROFILE_ID \
        -c "{\"frontend_dast\": {\"scope\": {\"crawling\": {\"allowlist\": $SCOPE_RULES}}, \"hotstart\": $AFFECTED_PAGES}}" \
        --watch
  only:
    - merge_requests
  variables:
    ESCAPE_API_KEY: $ESCAPE_API_KEY

Benefits of Incremental Scanning

Validate the generated overrides before starting a scan: Check that they include the affected routes and handle empty results explicitly in your pipeline. Escape uses the supplied configuration as the scan scope. See API Testing Scope and WebApp Testing Scope for rule behavior.

  • Focused Testing: Select the endpoints and pages affected by your changes.
  • Actionable Feedback: Review findings from the selected scope in your merge workflow.
  • Control Over Each Run: Adjust scope, authentication, and test settings through configuration overrides.
  • Testing Before Production: Run scans at the merge request stage to review and address findings before deployment.