Veridical10 min readArticle

Python PR Security Checks: 5 Checks That Keep Merges Moving

Python PR Security Checks: 5 Checks That Keep Merges Moving

Geometric pull request security gate illustration

On every Python pull request, run a dependency check on changed manifests, static analysis aimed at the diff, and a secrets scan on changed files. Use dependency review or pip-audit for packages, CodeQL and Bandit for code, and treat confirmed secrets as blockers. Gate merges only on new high or critical findings, so pre-existing debt never stalls your team.


TL;DR:

  • Run dependency submission and review in the same workflow; otherwise, review may start before the snapshot exists and falsely report no issues.
  • Require a second reviewer for changes to login, permissions, or outbound requests, because scanners cannot reliably catch business logic and authorization flaws.
  • Limit Bandit to changed paths, filter by severity and confidence, and compare results with a JSON baseline so accepted findings do not recur.
  • Use CodeQL overlay analysis or report only changed lines, cache by CLI version and language, and run a full scan if caching fails.
  • Run secret detection both before commit and in CI, and rotate any exposed credential even when the scanner catches it before merge.

Veridical
Catch critical defects before merging
Veridical reviews GitHub pull requests with verified findings, detailed summaries, and inline evidence to help teams spot security risks.
Explore Veridical

Table of Contents

What should every Python PR security check include?

Run these in order on every pull request. Each step is cheap on its own and catches a different class of problem.

  1. Dependency check. Run the dependency review action or pip-audit on changed manifests and lockfiles. Fail the PR if it introduces a new high or critical CVE. You can enforce this across an organization with repository rulesets.
  2. Static analysis on the diff. Run CodeQL in diff-informed or overlay mode, and run Bandit on changed files or against a baseline.
  3. Secrets scan. Use a regex and entropy scanner in pre-commit and again in CI. Escalate confirmed hits to a human.
  4. Supply-chain metadata. For each new package, look at freshness, maintainers, and license as part of dependency review.
  5. Quick manual checks. Pair automation with a human look at authentication and authorization changes, new external integrations, and unusual data flows.

That last step matters because the OWASP Secure Code Review Cheat Sheet recommends a hybrid approach: tools cover baseline checks, while people review the business logic and authorization issues that tools cannot reliably detect.

A few habits keep the checklist workable:

  • Keep the manual review short and tied to the diff.
  • Treat any change that touches login, permissions, or outbound requests as needing a second pair of eyes.
  • Record why a finding was dismissed, so the next reviewer does not repeat the work.

How do you configure Bandit, CodeQL, dependency review, and secrets scanners?

Each tool needs a few deliberate settings. Left at defaults, they either flood the PR or miss what you care about.

  • Bandit. Bandit analyzes the AST for issues such as SQL injection, subprocess misuse, and weak crypto. Filter by severity and confidence (for example, -lll for high severity only), limit runs to changed paths, and compare against a JSON baseline so known, accepted findings stay quiet. The getting started guide shows how to generate that baseline.
  • CodeQL. Trigger scanning on pull_request so new vulnerabilities are caught before they land, as the code scanning workflow options describe. Prefer diff-informed or overlay analysis, and let results appear as alerts on the PR.
  • Dependency review and pip-audit. Run dependency submission first, then the review action. Set the failure threshold to the severities you choose, and add license rules if your policy needs them.
  • Secrets scanning. Combine a pre-commit check with a CI scan. Triage only high-confidence hits, and rotate any credential that was exposed, even briefly.

Pro Tip: Centralize settings such as paths-ignore and severity thresholds in shared configuration, so two repositories never behave differently for the same code.

How do you wire the scans into GitHub Actions and branch protection?

Order and triggers decide whether your checks are trusted or ignored. A sound pattern looks like this:

  1. Run dependency submission so GitHub has a snapshot to compare against.
  2. Run the dependency review action against that snapshot.
  3. Run CodeQL in diff-informed mode.
  4. Run Bandit and the secrets scan.
  5. Mark the dependency review and code scanning workflows as required checks in branch protection or a ruleset, so a failure blocks the merge. The dependency review documentation is explicit that gates should be designed with developer experience in mind.

The gating policy should fail only on newly introduced high or critical findings. Require human sign-off for any change to the policy itself, and let teams acknowledge legacy issues through baselines rather than disabling a check. If you want a broader view of how merge gates and review evidence fit together, our guide to CI quality gates in GitHub goes deeper, and the software release checklist from Odesa covers gates and human checks at release time.

Race conditions are the quiet failure here. If dependency submission and review run as separate workflows, the review can start before the snapshot exists and report nothing. Run both in the same workflow, or add retry with backoff when they must be separate.

Pro Tip: Name your required workflows clearly and keep them stable. Renaming a workflow can silently drop it from the required list.

How do you avoid false positives with baselines and allowlists?

A gate that cries wolf gets bypassed. The goal is to keep every blocking signal worth reading.

  • Generate a Bandit JSON baseline so accepted findings stop appearing in CI.
  • Use allowlists with a written rationale and an expiration date for each legacy exception, in the spirit of the pipeline-armor project, which describes false-positive fatigue as a core reason gates lose effect.
  • Set severity thresholds so only high and critical issues block, and route medium and low findings to a triage queue.
  • When two scanners disagree, require human triage, and prefer findings that carry inline evidence or a reproducible check before blocking a merge.
Control What it does Review cadence
Baseline Hides known, accepted findings At each release
Allowlist entry Documents a legacy exception Until its expiration date
Severity threshold Blocks only on high or critical When policy changes
Human triage Resolves scanner disagreements Per disputed finding

How do you keep PR security checks fast on large repositories?

Slow checks get skipped, so speed is a security feature. Incremental analysis in the CodeQL CLI offers several options:

  • Diff-informed reporting limits alerts to lines the PR added or modified.
  • Overlay mode builds a lightweight layer on a cached base database instead of rebuilding from scratch.
  • Cache keys should include the CodeQL CLI version and language set, with a fallback to a full scan when the cache is missing or incompatible.

Check the minimum CLI bundle version for Python overlay and diff support, and confirm your Git setup meets the overlay requirements. On the CI side, filter SARIF output to the diff ranges so annotations stay stable and predictable between runs.

What does a copyable PR security workflow look like?

Start with this sequence and adjust it per repository:

  1. Dependency submission
  2. Dependency review
  3. Secrets scan
  4. CodeQL in diff-informed mode
  5. Bandit
  6. pip-audit

Keep submission and review in one workflow, or set retries and sensible timeouts if you split them, so a missing snapshot does not look like a clean result. For configuration, set Bandit severity flags, list the languages in your CodeQL matrix, and use paths-ignore to skip docs and tests where they add noise. Bandit also has a documented GitHub Actions integration with inputs for severity, confidence, excluded paths, and a baseline file.

Pro Tip: Add a lightweight secrets check to pre-commit. Catching a leaked key before it is pushed beats rotating it afterward.

Why do we trust evidence over raw scanner output?

Why do we trust evidence over raw scanner output? — overview diagram

Scanners are good at coverage and weak at judgment. Most of the pain in PR security comes from the gap between an alert and a decision. When a finding arrives without evidence, someone has to re-derive it, and that re-triage is where time and trust drain away.

Our view is that a finding earns a place in a merge decision only when it is tied to concrete evidence a reviewer can check. A calibrated advisory score then gives you something defensible to gate on, with an audit trail instead of a gut call.

— Łukasz

How does Veridical fit into your PR security workflow?

If you want the evidence-first approach without building it yourself, our pull request reviews give you verified findings, detailed summaries, and a calibrated advisory score you can wire into merge gating. Teams that maintain large repositories, or need reproducible PR evidence and less triage time, tend to benefit most.

Veridical

You can start with the free reviews for open source projects, read how we handle your code on our security and data handling page, or compare the Launch tier, Standard at $39 per month, and Pro at $69 per month on the pricing page. Connect a repository, open a pull request, and see the evidence behind each finding.

FAQ

What security checks should every Python pull request run?

Run a dependency check on changed manifests, static analysis on the diff, and a secrets scan. Tools such as dependency review, CodeQL, and Bandit cover the first two. Add a short manual review for authentication and data-flow changes.

Should PR security checks block merges?

Block only on newly introduced high or critical findings, and on confirmed secrets. Failing on pre-existing issues stalls teams and teaches them to bypass the gate. Send lower severities to a triage queue instead.

How do I stop Bandit from flooding my pull requests?

Filter by severity and confidence, limit runs to changed files, and compare against a JSON baseline of accepted findings. The Bandit documentation explains how to generate that baseline. Revisit the baseline at each release.

How can I make CodeQL faster on pull requests?

Use diff-informed or overlay analysis so only changed code is reported and a cached base database is reused. Include the CLI version and languages in the cache key. Fall back to a full scan when the cache is unavailable.

Do automated PR checks replace manual code review?

No. The OWASP cheat sheet recommends tools for baseline checks and people for business logic and authorization. Use both, with automation handling the repetitive part.

Sources

Authoritative docs and databases to consult

For configuration details and policy decisions, go to the primary documentation: