CI/CD Integration

Overview

Pensar provides a CLI tool and API for integrating security scanning directly into your CI/CD pipeline. Run automated pentests on every pull request, commit, or deployment to catch vulnerabilities before they reach production.

Installation

Install the Pensar CI package globally:

$npm install -g @pensar/ci

Or add it as a dev dependency:

$npm install --save-dev @pensar/ci

View the source code and additional examples on GitHub.

Configuration

Required Environment Variables

VariableDescription
PENSAR_API_KEYYour Pensar API key
PENSAR_PROJECT_IDYour Pensar project ID

Optional Environment Variables

VariableDescriptionDefault
PENSAR_ENVIRONMENTdev, staging, or productionproduction
PENSAR_SCAN_LEVELScan depth: priority or fullfull

You can find your Project ID in the project settings page in the Pensar Console. Click the copy button next to the ID to copy it to your clipboard.

CLI Usage

Trigger a Scan

$pensar scan [options]

Options:

OptionDescription
-p, --project <id>Project ID (or use PENSAR_PROJECT_ID)
-b, --branch <branch>Branch to scan
-l, --level <level>Scan level: priority or full
--no-waitDon’t wait for scan completion
-e, --environment <env>Environment: dev, staging, production

Examples:

$# Basic scan using environment variables
$pensar scan
$
$# Scan a specific branch
$pensar scan --branch main
$
$# Quick priority scan without waiting
$pensar scan --level priority --no-wait
$
$# Full scan with explicit project ID
$pensar scan --project abc123-def456 --branch develop

Check Scan Status

$pensar status <scanId>

Example:

$pensar status abc123-def456-789

CI/CD Examples

GitHub Actions

Scan every pull request before merging:

1name: Pensar Security Scan
2
3on:
4 pull_request:
5 branches: [main, master, develop]
6
7jobs:
8 security-scan:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/checkout@v4
12
13 - uses: actions/setup-node@v4
14 with:
15 node-version: '20'
16
17 - name: Install Pensar CI
18 run: npm install -g @pensar/ci
19
20 - name: Run Security Scan
21 env:
22 PENSAR_API_KEY: ${{ secrets.PENSAR_API_KEY }}
23 PENSAR_PROJECT_ID: ${{ secrets.PENSAR_PROJECT_ID }}
24 run: pensar scan --branch ${{ github.head_ref }}

GitLab CI

Add to your .gitlab-ci.yml:

1stages:
2 - security
3
4pensar-scan:
5 stage: security
6 image: node:20
7 rules:
8 - if: $CI_PIPELINE_SOURCE == "merge_request_event"
9 - if: $CI_COMMIT_BRANCH == "main"
10 before_script:
11 - npm install -g @pensar/ci
12 script:
13 - pensar scan --branch $CI_COMMIT_REF_NAME
14 variables:
15 PENSAR_API_KEY: $PENSAR_API_KEY
16 PENSAR_PROJECT_ID: $PENSAR_PROJECT_ID

Bitbucket Pipelines

Add to your bitbucket-pipelines.yml:

1pipelines:
2 pull-requests:
3 '**':
4 - step:
5 name: Pensar Security Scan
6 image: node:20
7 script:
8 - npm install -g @pensar/ci
9 - pensar scan --branch $BITBUCKET_BRANCH
10
11 branches:
12 main:
13 - step:
14 name: Pensar Security Scan
15 image: node:20
16 script:
17 - npm install -g @pensar/ci
18 - pensar scan --branch main

Programmatic Usage

Use the CI package programmatically in your Node.js scripts:

1import { CI } from '@pensar/ci';
2
3// Run a scan and wait for completion
4const result = await CI.runScan({
5 projectId: 'your-project-id',
6 branch: 'main',
7 scanLevel: 'full',
8 wait: true,
9});
10
11console.log(`Scan completed with ${result.issuesCount} issues`);
12
13// Or use lower-level APIs
14const { scanId, label } = await CI.dispatchScan({
15 apiKey: process.env.PENSAR_API_KEY,
16 projectId: 'your-project-id',
17});
18
19// Check status
20const status = await CI.getScanStatus({
21 apiKey: process.env.PENSAR_API_KEY,
22 scanId,
23});
24
25console.log(`Scan ${label}: ${status.status}`);

Exit Codes

CodeMeaning
0Scan completed with no issues
1Scan found security issues or failed

By default, the CLI will exit with code 1 if any security issues are found. Use this to block PRs or deployments when vulnerabilities are detected.

Best Practices

For faster feedback on pull requests, use priority scans:

$pensar scan --level priority

Priority scans focus on the most critical vulnerability categories, providing results in minutes rather than hours.

Schedule comprehensive scans on your main branch:

  • Run full scans after merging to main
  • Use scheduled workflows for nightly full scans
  • Full scans provide the most thorough coverage

Never hardcode API keys in your pipeline configuration:

  • Use GitHub Secrets, GitLab CI Variables, or Bitbucket Repository Variables
  • Rotate API keys regularly
  • Use separate API keys for different environments

Integrate scan results into your workflow:

  • Block merges when critical issues are found
  • Send notifications to Slack or email
  • Track issues in your project management tool
  • Use the Pensar Console for detailed analysis

API Reference

Dispatch Scan

POST /ci/dispatch

Headers:

  • Authorization: Bearer <api_key> or x-api-key: <api_key>
  • Content-Type: application/json

Request Body:

1{
2 "projectId": "string",
3 "branch": "string (optional)",
4 "scanLevel": "priority | full (optional)"
5}

Response:

1{
2 "scanId": "string",
3 "label": "string",
4 "status": "queued"
5}

Get Scan Status

GET /ci/status/{scanId}

Headers:

  • Authorization: Bearer <api_key> or x-api-key: <api_key>

Response:

1{
2 "scanId": "string",
3 "label": "string",
4 "status": "queued | running | completed | failed | paused",
5 "startedAt": "string | null",
6 "completedAt": "string | null",
7 "errorMessage": "string | null",
8 "issuesCount": 0,
9 "reportReady": false
10}

Next Steps