Set Up Continuous Pentesting in Your CI: A 10-Minute Guide
May 2026
Your pipeline already has layers. Linters catch style issues. Tests catch regressions. AI code review catches quality and security patterns in the diff. But none of those layers run the application.
This matters more now than it did a year ago. Stripe's coding agents merge 1,300 PRs per week. Ramp's Inspect agent authors 30% of all merged PRs. Some engineers at Anthropic report 100% AI-written code. At that volume, "I'll review the diff" is not a security strategy โ it's a coping mechanism for a pipeline you don't trust.
Consider a textbook example: a coding agent opens a PR adding a credit transfer endpoint. The code checks the sender's balance, validates it's sufficient, then executes the transfer. Every line is correct. The linter passes. Tests pass. The AI reviewer sees proper validation logic. Static scanners find nothing wrong with the code.
The bug is in the timing. At runtime, an attacker sends 10 concurrent transfer requests for their full balance. All 10 pass the balance check before any of them deduct โ no row-level locking, no atomic transaction. $100 becomes $1,000. It's a textbook TOCTOU race condition, and it only exists when real requests hit a real database under concurrency. Runtime validation is the missing layer.
Prerequisites
- โธA Pensar account and API key (grab one from the Console under Settings โ CI/CD)
- โธNode.js 22+
- โธA CI pipeline you want to protect
Step 1 โ Test Locally
Before touching CI config, verify the CLI works on your machine.
npm install -g @pensar/ci export PENSAR_API_KEY=your_key_here pensar pentest --environment dev
Exit code 0 means clean. Exit code 1 means findings โ this is what CI will use to gate merges.
Step 2 โ Pick Your Pattern
GitHub Actions โ PR Pentest
name: Pensar PR Pentest
on:
pull_request:
branches: [main]
jobs:
pentest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm install -g @pensar/ci
- run: pensar pentest --branch ${{ github.head_ref }} --environment staging
env:
PENSAR_API_KEY: ${{ secrets.PENSAR_API_KEY }}Step 3 โ Graduate to Gating
Start non-blocking. Let results flow to PRs and dashboards for a few weeks while your team calibrates signal vs noise. Then make it a hard gate:
- GitHub: Settings โ Branches โ Branch protection rules โ Require status checks โ add Pensar PR Pentest
- GitLab: Set
allow_failure: falseon the pentest job (this is the default) - Bitbucket: Repository settings โ Branch permissions โ add the pentest step as a required check