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 event | What Argus does |
|---|---|
opened | Records the PR, queues a review, sets the commit status to pending |
synchronize (new push) | Queues a fresh review against the new commit |
reopened | Queues a review |
closed / merged | Records 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
- Go to Settings → Integrations → Source Control.
- Click Connect on the GitHub card (or Add GitHub account / repos if you already have one connected).
- Choose the account or organization, and pick the repositories.
- 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
| Permission | Why |
|---|---|
| Pull requests: read & write | Read the diff, post the review |
| Contents: read | Fetch the changed files to analyse them |
| Contents: write | Only for the agentic fix flow, create the branch and commit the fix |
| Commit statuses: write | Post the Argus / security-review check |
| Metadata: read | List 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
| Verdict | When |
|---|---|
| Changes requested | Any CRITICAL or HIGH finding on the changed lines |
| Comment | Everything 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
| Limit | Value |
|---|---|
| Changed files reviewed per PR | 100 |
| Per-file size | 512 KiB, larger files are skipped |
| Off-diff findings listed in the summary | 30 |
| Binary files | Skipped |
Each auto-review costs 5 credits, charged on success only.
The commit status
Argus posts a commit status with the context:
Argus / security-review
| State | When | Description |
|---|---|---|
pending | Review queued | Argus security review queued… |
pending | Review running | Argus is reviewing this PR… |
failure | Changes requested | Blocked: N security finding(s) need review |
success | Comment verdict | N low-risk finding(s), marked not blocking, or No security issues found in the changed lines |
error | The review pipeline itself failed | Argus 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.
Option A, a GitHub org ruleset (recommended)
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:
- Add an organization or repository secret
ARGUS_API_KEY. Mint the key in Settings → API keys. - Set
ARGUS_URLto your Argus instance URL. - Require the check named
Argus Security / reviewin branch protection or a ruleset.
Two different check names. Option A requires
Argus / security-review, the status the GitHub App posts. Option B requiresArgus 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 response | Meaning |
|---|---|
| Changes requested | The review requested changes |
| Commented | The review posted comments only |
| Queued for review / Reviewing… | The job is waiting or running |
| Review failed | The review pipeline errored |
| Not reviewed | Argus never reviewed this PR. This is not the same as "no findings" |
| At merge | Meaning |
|---|---|
| Merged with N unresolved | At the instant of merge, N Argus findings were still unresolved. A historical fact. It does not change when the findings are later fixed |
| Merged clean | Nothing was unresolved at merge |
| Not recorded | The 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
- Integrations, the MCP server, CI gate script, Slack, trackers
- Policies and gates, write the rule that decides pass or fail