Overview
Shieldome exposes a REST API that lets you trigger scans, poll for results, and fail your build if critical vulnerabilities are found. This guide covers the general pattern that works on any CI/CD platform — Jenkins, CircleCI, Azure DevOps, TeamCity, Drone, or custom scripts.
If you use GitHub Actions, GitLab CI, or Bitbucket Pipelines, platform-specific guides with copy-paste YAML are available in the sidebar.
The integration pattern
Every CI/CD integration follows the same three steps:
- Trigger —
POST /api/scanwith your target URL and API key → receive ascan_id - Poll —
GET /api/scan/{scan_id}in a loop untilstatusiscompletedorfailed - Evaluate — count findings by severity, exit with code 1 if threshold is breached
Step 1 — Store your API key
Never hardcode the API key in your pipeline file. Store it as a secret in your CI/CD platform:
| Platform | Where to add it |
|---|---|
| Jenkins | Manage Jenkins → Credentials → Global → Add Credentials (Secret text) |
| CircleCI | Project Settings → Environment Variables |
| Azure DevOps | Library → Variable groups → add as secret variable |
| TeamCity | Build Configuration → Parameters → add as password type |
| Drone CI | Repository → Secrets |
Reference it in your pipeline as $SHIELDOME_API_KEY (or the platform-specific syntax).
Step 2 — Trigger a scan (curl)
RESPONSE=$(curl -s -X POST https://your-shieldome-url/api/scan \
-H "Content-Type: application/json" \
-H "X-Shieldome-Key: $SHIELDOME_API_KEY" \
-d '{
"target_url": "https://your-app-url.com",
"scan_type": "vuln",
"scan_authorized": true
}')
SCAN_ID=$(echo "$RESPONSE" | python3 -c \
"import sys,json; print(json.load(sys.stdin)['scan_id'])")
echo "Scan started: $SCAN_ID"
Step 3 — Poll for completion
for i in $(seq 1 72); do
STATUS=$(curl -s \
-H "X-Shieldome-Key: $SHIELDOME_API_KEY" \
"https://your-shieldome-url/api/scan/$SCAN_ID" \
| python3 -c "import sys,json; print(json.load(sys.stdin).get('status',''))")
echo "[$i] status=$STATUS"
[ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break
sleep 10
done
Step 4 — Evaluate and fail the build
RESULT=$(curl -s \
-H "X-Shieldome-Key: $SHIELDOME_API_KEY" \
"https://your-shieldome-url/api/scan/$SCAN_ID")
CRITICAL=$(echo "$RESULT" | python3 -c "
import sys, json
d = json.load(sys.stdin)
vulns = d.get('results', {}).get('vulnerabilities', [])
print(sum(1 for v in vulns if v.get('severity') == 'critical'))
")
echo "Critical findings: $CRITICAL"
if [ "$CRITICAL" -gt 0 ]; then
echo "BUILD FAILED: $CRITICAL critical vulnerability/vulnerabilities detected."
exit 1
fi
echo "No critical vulnerabilities found."
Python script variant
Some platforms don't have curl or make it awkward to pipe JSON through python3 -c. Save this as shieldome_scan.py in your repository and call it from your pipeline:
#!/usr/bin/env python3 # shieldome_scan.py # Usage: python shieldome_scan.py --url https://your-app.com --fail-on critical import argparse, os, sys, time import requests def main(): p = argparse.ArgumentParser() p.add_argument('--url', required=True, help='Target URL to scan') p.add_argument('--type', default='vuln', choices=['vuln','perf','both']) p.add_argument('--fail-on', default='critical', choices=['critical','high','medium']) p.add_argument('--timeout', type=int, default=720, help='Max seconds to wait') args = p.parse_args() base = os.environ.get('SHIELDOME_BASE_URL', 'https://your-shieldome-url') key = os.environ['SHIELDOME_API_KEY'] headers = {'X-Shieldome-Key': key, 'Content-Type': 'application/json'} # Trigger r = requests.post(f'{base}/api/scan', json={ 'target_url': args.url, 'scan_type': args.type, 'scan_authorized': True }, headers=headers, timeout=30) r.raise_for_status() scan_id = r.json()['scan_id'] print(f'Scan started: {scan_id}') # Poll deadline = time.time() + args.timeout data = {} while time.time() < deadline: time.sleep(10) data = requests.get(f'{base}/api/scan/{scan_id}', headers=headers, timeout=15).json() status = data.get('status', '') print(f' status={status} progress={data.get("progress", 0)}%') if status in ('completed', 'failed'): break else: print('Timeout waiting for scan.', file=sys.stderr) sys.exit(2) # Evaluate vulns = data.get('results', {}).get('vulnerabilities', []) counts = {'critical': 0, 'high': 0, 'medium': 0, 'low': 0, 'info': 0} for v in vulns: sev = v.get('severity', 'info') counts[sev] = counts.get(sev, 0) + 1 print('\n=== Shieldome Results ===') for sev, cnt in counts.items(): print(f' {sev.upper():<10} {cnt}') thresholds = ['critical', 'high', 'medium', 'low', 'info'] threshold_idx = thresholds.index(args.fail_on) failures = [s for s in thresholds[:threshold_idx+1] if counts.get(s, 0) > 0] if failures: print(f'\nFAILED: {", ".join(failures)} findings detected.') sys.exit(1) print('\nAll checks passed.') if __name__ == '__main__': main()
Then in your pipeline:
pip install requests -q python shieldome_scan.py --url https://your-app.com --fail-on critical
Jenkins example (declarative pipeline)
pipeline {
agent any
environment {
SHIELDOME_API_KEY = credentials('shieldome-api-key')
}
stages {
stage('Deploy') { steps { echo 'Deploy your app here' } }
stage('Security Scan') {
steps {
sh '''
pip install requests -q
python3 shieldome_scan.py \
--url https://your-app.com \
--fail-on critical
'''
}
}
}
post {
always {
archiveArtifacts artifacts: 'shieldome-report.pdf', allowEmptyArchive: true
}
}
}
Fail threshold reference
--fail-on | Build fails when |
|---|---|
critical | Any critical finding is detected (default, strictest) |
high | Any critical or high finding is detected |
medium | Any critical, high, or medium finding is detected |