> For the complete documentation index, see [llms.txt](https://cortex-docs.paloaltonetworks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cortex-docs.paloaltonetworks.com/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/pull-request-scan-workflow.md).

# Pull request scan workflow

The workflow proceeds from enabling the gate, through verifying that the gate fires, to investigating a specific block and restoring a gate that has gone silent.

```mermaid
flowchart TD
    A[Enable pull request scanning on the repository] --> B[Developer opens or updates a pull request]
    B --> C[Cortex Cloud scans the diff and posts a status check]
    C --> D{PR status?}
    D -->|Blocked| E[Investigate the blocked pull request]
    D -->|Passed or Passed With Issues| F[Merge proceeds]
    E --> G[Identify the blocking policy and remediate in the branch]
    G --> B
    F --> H{Scan health degraded?}
    H -->|Yes| I[Treat the merge as ungoverned and diagnose]
    H -->|No| J[Enforcement confirmed]
```

## Enable pull request scanning on a repository

Pull request scanning is configured per repository. A repository with pull request scanning disabled never gates a merge, regardless of which policies are enabled at the tenant level.

#### Prerequisites

An active VCS integration with the repository onboarded, and the **Data Sources (View/Edit)** permission. See [Reference I: Permissions](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-i-permissions.md).

#### Steps

1. Navigate to **Settings** > **Data Sources & Integrations**, and search for the provider.
2. Select the provider. The provider view displays all instances and the status of each instance.
3. Select an instance. The instance view displays the connected repositories, the status of each repository, and the scan coverage of each repository.
4. Right-click the target repository and select **Scan Configuration**.
5. Confirm **Active Scanners**. Pull request scanning evaluates the diff with the scanners enabled here. A scanner disabled in this configuration never contributes a finding to a pull request scan and never blocks a merge.
6. Configure **PR Scanning**:
   * **Scan PR**: Trigger a security scan automatically when a pull request opens or receives a new commit. Enable this setting for every repository whose branches reach production
   * **Fail PR on scan error**: Fail the pull request automatically when a scanner fails, rather than allowing the merge on the strength of a scan that did not run. This setting is disabled by default, which means an errored scan does not block the merge until you enable the setting
7. Select **Save**.
8. Configure the status check as a required check on the target branch, in the version control system. Cortex Cloud reports the merge decision as a status check named **Cortex AppSec - Code analysis**; the version control system decides whether a failing check stops a merge. Without this step the gate records violations and does not enforce them.
9. Verify the configuration. Open a pull request against the repository — or push a commit to an open pull request — and confirm that the pull request receives the **Cortex AppSec - Code analysis** status check and that a corresponding row appears in the Pull Request Scans inventory. A pull request scan cannot be triggered from Cortex Cloud, so a pull request is the only way to exercise the configuration.

**Result:** Pull requests opened against the repository trigger a scan, receive a status check that links back to the scan result in Cortex Cloud, and — once the status check is required on the target branch — cannot merge while the check fails.

> **Important:** If no status check and no inventory row appear for a pull request you opened, the gate is not running. Do not interpret the absence as a clean result — an unscanned pull request produces no row, no status check, and no warning. Follow [Diagnose a gate that stopped firing](#diagnose-a-gate-that-stopped-firing).

> **Important:** Enabling **Scan PR** produces findings and pull request comments, and does not by itself block any merge. Blocking requires an enabled Unified Application Security Policy with the **PR Scan** trigger and the **Block PR** action. Two policy properties determine who is affected and when: the policy **scope**, which limits enforcement to an asset or application boundary, and the **grace period**, which defers the **Block PR** action for a configured interval after the policy is enabled. Review both before a rollout — and before concluding that a silent gate is broken, because a policy inside its grace period blocks nothing by design. See [Unified Application Security Policies](/application-security/application-security-posture-management-aspm/unified-application-security-policies.md).

> **Caution:** Enabling **Fail PR on scan error** converts every scanner failure into a blocked merge. The setting closes the gap where a broken scanner silently permits an unscanned change, and it also stops merges during a provider outage. Enable the setting for repositories serving business-critical applications, and pair the change with a monitored path for diagnosing scan failures.

> **Note:** For the complete scan configuration surface, including the settings shared with branch periodic scans, see [Reference F: Pull request scan configuration settings](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-f-pull-request-scan-configuration-settings.md).

## Verify that scans are active across all projects

A configured gate and an enforcing gate are different states. Establish which repositories are actually returning pull request scan results before reporting prevention coverage.

**Prerequisites:** The `Application Security PR Scans View` permission to read the inventory, and an API key to establish the gated population in step 2. Enabling the gate on a repository the assessment identifies as ungated additionally requires the **Data Sources (View/Edit)** permission, which none of the scan-viewing permissions grant — confirm the assignee holds that permission before delegating remediation.

> **Important:** The repositories absent from this inventory matter more than the rows present in it. A repository with pull request scanning disabled, a repository receiving only forked contributions, and a repository whose webhook subscription is failing all produce the same empty result as a repository with no pull request activity. Never infer coverage from row counts alone. Step 2 establishes the disabled population; the integration health view described in [Diagnose a gate that stopped firing](#diagnose-a-gate-that-stopped-firing) establishes the failing-webhook population.

1. Navigate to **Application Security** > **Scans** > **Pull Request Scans**.
2. Establish the gated population — the repositories where **Scan PR** is enabled. The inventory does not report this, and no console view lists pull request scanning state across repositories. Retrieve it programmatically
   1. List the onboarded repositories with `GET /public_api/appsec/v1/repositories`
   2. Read `prScanning.isEnabled` for each returned asset with `GET /public_api/appsec/v1/repositories/{assetId}/scan-configuration`.\
      The repositories returning `false` are ungated and produce no rows in this inventory. See [Repository as an asset](/application-security/application-security-posture-management-aspm/repository-as-an-asset.md).
3. Use the filter bar to filter by repository, organization, scanned branch, pull request ID, PR status, and scan health. Bound the assessment to the period under review, so the returned rows are the commit scans of that period rather than every merge the inventory has accumulated. Where the inventory exposes a **Scan Date** range filter, apply it — see [Scan Date filter](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-b-inventory-columns.md#scan-date-filter) for the availability caveat and for what the filter can and cannot establish.
4. Filter **PR Status** to **Failed** over the same period you use for posture review. The returned rows are the merges the gate actually stopped. and several rows can belong to one pull request — count distinct **Pull Request ID** values, not rows, to establish how many pull requests the gate stopped. Zero **Blocked** rows for a gated, actively developed repository is not self-interpreting: the cause is either that no risk was introduced, that no policy carries the **Block PR** action for the finding types that repository produces, or that a matching policy is still inside its grace period. Resolve the ambiguity against the policy set rather than by adjusting the date range. The rows that remain are not a clean population — **Passed** covers both a scan that found nothing and a scan whose issues matched no blocking policy, and the column does not separate them. Read the **Issues** count on a **Passed** row to distinguish the two.
5. Enable the **Blocking Policies** column from the column settings icon in the inventory toolbar, then review which policies appear. Compare the policies that fired against the policies enabled for the **PR Scan** trigger — an enabled **Block PR** policy that never appears is either well-targeted or scoped away from the repositories that need it. Select a blocking policy name to open the policy in **Policy Management**.
6. Filter **Scan Health** to **Error** and to **Partially** (completed). These rows are merges evaluated on incomplete evidence. Treat every one of them as ungoverned regardless of the PR status the row reports.
7. Filter **Business Application Names** to one business-critical application at a time, and address the returned rows before moving to the next application. The inventory carries application names but not application criticality, and the column supports neither sorting nor grouping because a repository can belong to several applications. Establish the criticality ordering outside this inventory first: navigate to **Application Security** > **Application Management** > **Business Applications**, sort the table by the **Business Criticality** column, and record the application names in descending criticality order. The criticality tiers that qualify as business-critical are a governance decision — confirm the threshold with the AppSec Manager rather than setting the threshold at the filter. A repository that is not mapped to a business application returns an empty value — treat an empty value as unknown criticality requiring mapping, not as low criticality. To map repositories to applications, see [Criteria](/application-security/application-security-posture-management-aspm/applications/defining-business-applications.md).

**Result:** You hold the gated repository population, the set of commit scans the gate stopped, the policies that stopped them, and the merges that passed on incomplete evidence.

**Verify the assessment is complete.** Confirm all of the following before reporting prevention coverage:

* Every repository returned by step 2 with `prScanning.isEnabled` set to `false` is either assigned for enablement or recorded as an accepted gap
* Every gated, actively developed repository returning zero **Blocked** rows has been resolved against the policy set, rather than left ambiguous
* Every reported count of blocked pull requests is a count of distinct **Pull Request ID** values, not a count of **Blocked** rows
* Every row returned in step 6 is treated as ungoverned, regardless of the PR status the row reports
* The repositories that appear in no row at all have been accounted for through step 2 or through the integration health view — an absent repository is not a passing repository

Verify closure of an enablement handover by repeating step 2 and confirming that `prScanning.isEnabled` returns `true` for the repositories handed over.

> **Note:** Prevention Rate is a Cortex Cloud metric reported in the ASPM Command Center, computed over a defined window and scope — see [ASPM Command Center](/application-security/application-security-posture-management-aspm/aspm-command-center.md). Read the metric there rather than deriving a competing figure. To compute prevention across a custom period, use the method in [Public APIs for code security issues](/application-security/code-security/api-workflows-for-code-security-issues.md); the underlying PR scan endpoint and its blocking policy fields are documented in [Public APIs for scan management](https://app.gitbook.com/o/r4DIGbR5VLvkZy3gAYsu/sites/site_gHT7E/s/ZuJbX2x7VQJhNovscCwE/aspm-cicd-and-application-security/scan-management).

> **Note:** For the inventory columns and the underlying fields, see [Reference B: Inventory columns](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-b-inventory-columns.md).

## Investigate a blocked pull request

Open a scan result to determine what the scan found, which policy blocked the merge, and where each detection is resolved.

1. Select a scan row in the Pull Request Scans inventory. The side panel opens, titled with the pull request title rather than the repository name.
2. Review the **Overview** tab to establish the scope of the result:
   * **Organization**, **Repository**, and **Scanned Branch** identify the source branch of the pull request.
   * **PR Status** reports the policy evaluation result that determined the merge outcome.
   * **Scan Health** reports execution health. No **Rescan** control is present for a pull request scan.
   * **Commit ID** identifies the commit that triggered the scan. A pull request that received several commits produces several scan results, one for each commit.
   * **Scan Date** records when the scan started.
   * **Issues** and **Issues By Type** report the actionable records by severity and by scanner category.
   * **Findings** and **Findings By Type** report the raw detections by severity and by scanner category.
3. Identify the blocking policy from the **Blocking Policy** column on the inventory row, and select the policy name to open the policy in **Policy Management**. The policy defines the condition that stopped the merge and is the only place to change that condition.
4. Select the issue category tab that matches the detection you are investigating — **Vulnerabilities**, **Configurations**, **Secrets**, **Package Integrity or Malicious Packages**. The **Package Integrity** tab presents two tables, **Licenses** and **Package Operational Risk**; see [Reference G: Scanner to issue category mapping](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-g-scanner-to-issue-category-mapping.md).
5. Select an issue in the table to open the issue side card within the scan management context, then select the **Findings** tab to review the underlying evidence.
6. Route the issue to the inventory that owns resolution for the issue category, using [Reference E: Issue category routing](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-e-issue-category-routing.md).
7. Confirm the fix on the next commit. Remediating a pull request scan issue means changing the code in the source branch and pushing the change — the new commit triggers a new scan, and the status check updates. There is no rescan action and no suppression path inside the scan inventory.

> **Caution:** Blocking a merge does not undo an exposure the push already created. Treat a secret detected by a pull request scan as a containment task with a rotation deadline, not as a code-cleanup task that the block resolved.

**Result:** The block is attributed to a specific policy and a specific finding, and the path to clearing the gate is a commit rather than an override.

> **Important:** An automatic fix pull request is not offered for a pull request scan issue, because the branch a fix would target is the branch already under review. Apply the change directly in the source branch of the pull request under review.

> **Note:** The developer who opened the pull request does not need access to Cortex Cloud to act on the result. Cortex Cloud posts the findings as a pull request comment in the version control system, and the status check links back to the full scan result. See [Reference H: Pull request comment feedback](/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/references/reference-h-pull-request-comment-feedback.md).

## Diagnose a gate that stopped firing

A pull request scan that never runs produces no error and no row. Diagnose the silence by working from the most common cause to the least.

1. Confirm that **Scan PR** is enabled for the repository. Navigate to **Settings** > **Data Sources & Integrations**, select the provider and instance, right-click the repository, and select **Scan Configuration**.
2. Confirm the pull request source. A pull request opened from a forked repository is ignored and produces no scan. Enforce forked contributions with branch protection rules in the version control system.
3. Review the health of the integration instance. Select the instance, then select **Review health**. Errors are reported per repository with a specific **Error Type**.
4. Correct the cause identified by the **Error Type** value. A **Webhook subscription** error stops pull request scanning specifically, while periodic scanning continues on its schedule — which is why a repository can show healthy periodic scans and no pull request scans at the same time. For the full error type reference, see Branch periodic scans.
5. Verify recovery by opening a new pull request, or by pushing a commit to an open pull request, and confirming that a new row appears in the Pull Request Scans inventory with a status check on the pull request.

**Result:** The gate is either restored and confirmed by a fresh scan result, or the cause is attributed to a specific integration error awaiting correction.

> **Caution:** A repository whose webhook subscription has failed continues to report healthy branch periodic scans while every pull request merges ungated. The periodic baseline then grows with risk that the gate should have stopped. Treat a webhook subscription error as an enforcement outage, not as a reporting inconvenience.

> **Note:** The `ERROR` and `IN_PROGRESS` wire values resolve differently in the console. `IN_PROGRESS` renders as **In Progress** and is available as a **PR Status** filter option. `ERROR` renders as no **PR Status** value at all — the console surfaces no **Error** PR status and offers no **Error** option in the **PR Status** filter, and an errored scan reports **Error** under **Scan Health** instead. `ERROR` nevertheless remains a valid API scan-status value. Automation must handle it without assuming a corresponding console **PR Status** value exists.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cortex-docs.paloaltonetworks.com/application-security/code-security/application-security-scans-management/manage-scans-through-the-tenant-ui/pull-request-scans/pull-request-scan-workflow.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
