Guide · 4 min
Add XploitScan to GitLab CI
Drop a single job into your .gitlab-ci.yml and get security scans on every merge request. Findings ship back as a downloadable job artifact; the pipeline fails if a critical vulnerability lands in the diff.
Add the job
Paste the block below into your .gitlab-ci.yml, or create the file at your project root if you don't have one yet.
# .gitlab-ci.yml
# Add this job to an existing pipeline. Runs on every merge request
# and on commits pushed to main.
xploitscan:
stage: test
image: node:20-alpine
script:
# Install + scan. The CLI exits 0 on findings; we control the gate via
# the grep below so we can be precise about severity.
- npm install -g xploitscan@^1.0.0
- npx xploitscan scan . --format json --no-ai > xploitscan-results.json || true
- npx xploitscan scan . # human-readable output in the job log
# Fail the pipeline if any critical findings are present. Swap
# "critical" → "high" to also fail on high-severity findings.
- 'if grep -q "\"severity\":\"critical\"" xploitscan-results.json; then
echo "Critical vulnerability detected — failing pipeline";
exit 1;
fi'
artifacts:
name: "xploitscan-report"
paths:
- xploitscan-results.json
expire_in: 30 days
when: always
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
(Optional) Unlock Pro rules
Without an API key the CLI runs 30 free rules. Generate a Pro key in Settings → API Keys and add it as a CI/CD variable in GitLab (Settings → CI/CD → Variables) named XPLOITSCAN_API_KEY. Check "Protect variable" and "Mask variable" so it's not echoed in job logs.
# Add under the job's `variables` section to unlock # all 158 Pro rules instead of the 30 free-tier rules. variables: XPLOITSCAN_API_KEY: $XPLOITSCAN_API_KEY
Commit and open a merge request
Commit the change, push, and open an MR. GitLab kicks off the pipeline; the xploitscan job shows up with the scan output in its log and xploitscan-results.json attached as a downloadable artifact.
Troubleshooting
- Pipeline fails on every MR? The
|| trueafter the scan is intentional — it lets the scan write the JSON even when findings exist. The fail gate is thegrepline. If you want report-only mode (no blocking), delete the grep block. - Only want to scan on MRs, not main? Remove the
$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHrule from therules:section. - Scan is slow on huge repos? Pass a path to scan a subset:
xploitscan scan ./src.
Using GitHub or Bitbucket instead? Same CLI, different pipeline wrapper.