Working the BacklogPull Request Security

Pull Request Security

Argus reviews every pull request and can block a merge until findings are resolved.

You will finish this page with Argus reviewing every pull request, and with a merge gate your team actually cannot bypass by accident.


What the GitHub App does

Once the Argus GitHub App is installed on a repository, every pull request gets reviewed automatically.

PR eventWhat Argus does
openedRecords the PR, queues a review, sets the commit status to pending
synchronize (new push)Queues a fresh review against the new commit
reopenedQueues a review
closed / mergedRecords the outcome. On merge, freezes an at-merge snapshot of unresolved findings and queues a re-scan of the project

Reviews run out-of-band, so GitHub gets a fast response and your PR is not blocked on the scan. A new push supersedes the previous review: each commit gets its own review, and duplicate webhook deliveries collapse into one job.

Argus never reviews a closed or merged pull request.


Installing the App

  1. Go to Settings → Integrations → Source Control.
  2. Click Connect on the GitHub card (or Add GitHub account / repos if you already have one connected).
  3. Choose the account or organization, and pick the repositories.
  4. GitHub redirects you back to Argus. Your connected accounts appear as chips on the GitHub card.

Installing on a second account is additive: the first stays connected. Each chip has its own × to disconnect.

If you are not an owner of the GitHub organization, GitHub records your install as a request. Nothing is connected until an owner approves it.

Permissions the App asks for

PermissionWhy
Pull requests: read & writeRead the diff, post the review
Contents: readFetch the changed files to analyse them
Contents: writeOnly for the agentic fix flow, create the branch and commit the fix
Commit statuses: writePost the Argus / security-review check
Metadata: readList the repositories you granted

Argus never asks for repository administration or organization administration. It cannot change your branch protection, and it cannot make its own check required. That is deliberate, see Blocking merges below.


What lands on the pull request

Argus posts a single GitHub review per commit.

Inline comments

One comment per finding that lands on a line the PR added. Each comment carries:

  • A severity emoji and the severity in bold
  • The finding title, with the type and CVE where they apply
  • The AI reviewer's explanation, with the underlying rule description as sub-text
  • Suggested fix: the remediation
  • A footer naming the rule that fired

Summary comment

Headed ## Argus security review, containing:

  • A note that this is an updated review, when a previous Argus review exists on the PR
  • Any linked issue-tracker tickets referenced by the branch, title or body
  • The verdict
  • A count line: **7** finding(s): 🟥 1 critical · 🟧 2 high · 🟨 3 medium · 🟦 1 low
  • A collapsed <details> block listing findings that exist in the repo but outside the changed lines

Verdicts

VerdictWhen
Changes requestedAny CRITICAL or HIGH finding on the changed lines
CommentEverything else, including a completely clean PR

Argus never posts an Approve. Approval is a human decision.

If GitHub rejects the inline comments because a position no longer maps to the diff, Argus retries with the summary only, so you always get the review.

Limits

LimitValue
Changed files reviewed per PR100
Per-file size512 KiB, larger files are skipped
Off-diff findings listed in the summary30
Binary filesSkipped

Each auto-review costs 5 credits, charged on success only.


The commit status

Argus posts a commit status with the context:

Argus / security-review
StateWhenDescription
pendingReview queuedArgus security review queued…
pendingReview runningArgus is reviewing this PR…
failureChanges requestedBlocked: N security finding(s) need review
successComment verdictN low-risk finding(s), marked not blocking, or No security issues found in the changed lines
errorThe review pipeline itself failedArgus review failed, pointing you to the logs

The status links back to the pull request.


Blocking merges

Argus posts the signal. You enforce it. Argus deliberately does not hold the GitHub Administration permission, so it cannot make its own check required, no security vendor should be able to rewrite your branch protection.

Making the check blocking is a one-time action you take with your own admin credentials. Two paths; pick one.

Go to Settings → Integrations → Merge protection to get both, pre-filled and copy-pasteable.

Covers every current and future repository in the organization in one step.

Save this as argus-ruleset.json:

{
  "name": "Argus security review (required)",
  "target": "branch",
  "enforcement": "active",
  "conditions": {
    "ref_name":        { "include": ["~DEFAULT_BRANCH"], "exclude": [] },
    "repository_name": { "include": ["~ALL"],            "exclude": [] }
  },
  "rules": [{
    "type": "required_status_checks",
    "parameters": {
      "strict_required_status_checks_policy": false,
      "required_status_checks": [{ "context": "Argus / security-review" }]
    }
  }]
}

Apply it once, as a GitHub organization owner:

gh auth login
gh api --method POST /orgs/<your-org>/rulesets --input argus-ruleset.json

From then on, a pull request whose Argus check is failure cannot merge into the default branch.

Option B, the Argus GitHub Action

Runs the scan inside your own CI with an Argus API key. Argus needs no GitHub write permission at all for this path.

Commit .github/workflows/argus-security.yml:

name: Argus Security
on:
  pull_request:
    branches: ["**"]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 50
      - name: Argus scan (blocks on Critical/High)
        env:
          ARGUS_API_KEY: ${{ secrets.ARGUS_API_KEY }}
          ARGUS_URL: https://your-argus-instance
          BASE: ${{ github.base_ref }}
        run: |
          set -euo pipefail
          git fetch --depth=50 origin "$BASE" >/dev/null 2>&1 || true
          git diff "origin/$BASE...HEAD" > pr.diff || git diff "origin/$BASE" > pr.diff
          if [ ! -s pr.diff ]; then echo "Argus: no diff to scan."; exit 0; fi
          jq -Rs '{jsonrpc:"2.0",id:1,method:"tools/call",params:{name:"scan_diff",arguments:{diff:.}}}' pr.diff > req.json
          curl -sS -X POST "$ARGUS_URL/api/mcp" \
            -H "Authorization: Bearer $ARGUS_API_KEY" \
            -H "content-type: application/json" -d @req.json > out.json
          if jq -e '.error' out.json >/dev/null 2>&1; then
            echo "Argus request failed:"; jq -r '.error.message' out.json; exit 2
          fi
          jq -r '.result.structuredContent.findings[]? | "[\(.severity)] \(.file):\(.line) \(.title)"' out.json
          BLOCK=$(jq '[.result.structuredContent.findings[]? | select((.severity|ascii_upcase)|test("CRITICAL|HIGH"))] | length' out.json)
          echo "Argus: $BLOCK blocking finding(s)."
          [ "$BLOCK" -eq 0 ]

Then:

  1. Add an organization or repository secret ARGUS_API_KEY. Mint the key in Settings → API keys.
  2. Set ARGUS_URL to your Argus instance URL.
  3. Require the check named Argus Security / review in branch protection or a ruleset.

Two different check names. Option A requires Argus / security-review, the status the GitHub App posts. Option B requires Argus Security / review, the workflow name plus job id of the Action above. They are separate checks. Require whichever path you chose; requiring both is fine too.

Marking it done

Once you have applied one of the options, click Mark as configured on the Merge protection card. This hides the dashboard reminder. It is a note to yourself, Argus does not inspect your GitHub settings to confirm it, so keep the ruleset under your own change control.


The AI review pass

By default, PR review runs the deterministic engines: Semgrep rules scoped to the changed lines, plus secret detection. AI is used to triage those results.

Turn on Settings → AI Scan → AI security review on pull requests to add an independent AI pass that finds issues on the changed code, logic errors, authorization gaps, injection and secrets that pattern rules miss. Its findings are merged with the rule findings and de-duplicated by location.

  • The toggle requires AI scanning to be enabled and an AI provider configured.
  • It saves the moment you flip it.
  • It costs credits per review.

How AI triage affects results

AI can only demote, and only conservatively. A finding is dropped only when the AI verdict is false positive and confidence is at least 0.7 and the severity is MEDIUM or below. CRITICAL and HIGH findings are never suppressed by AI.


Tracking pull requests

The Pull Requests page is the audit record.

Tabs: All · Open · Merged · Merged with unresolved.

KPIs: Pull requests seen · Open · Merged · Merged with unresolved.

Columns: Pull request · State · Argus response · Raised · Resolved · Remaining · At merge.

Argus responseMeaning
Changes requestedThe review requested changes
CommentedThe review posted comments only
Queued for review / Reviewing…The job is waiting or running
Review failedThe review pipeline errored
Not reviewedArgus never reviewed this PR. This is not the same as "no findings"
At mergeMeaning
Merged with N unresolvedAt the instant of merge, N Argus findings were still unresolved. A historical fact. It does not change when the findings are later fixed
Merged cleanNothing was unresolved at merge
Not recordedThe PR merged before Argus was watching, or no merge webhook arrived. An honest unknown, never reported as clean

Use Sync from GitHub with a project selected to import that repository's existing pull requests (up to 50).

Reviewing a PR on demand

curl -sS -X POST "$ARGUS_URL/api/graphql" \
  -H "Authorization: Bearer argus_live_xxx" \
  -H "content-type: application/json" \
  -d '{
    "query": "mutation { ReviewPullRequest(repo: "owner/name", prNumber: 42) { status message } }"
  }'

Next