Jenkins
Integrate BlockSecOps into your Jenkins pipeline. - Jenkins server - BlockSecOps account with API access - API key created --- 1. Go to BlockSecOps Settings →...
Last updated: January 14, 2026
Jenkins
Integrate BlockSecOps into your Jenkins pipeline.
Prerequisites
- Jenkins server
- BlockSecOps account with API access
- API key created
Setup
1. Create API Key
- Go to BlockSecOps Settings → API Keys
- Click Create Key
- Name: "Jenkins"
- Copy the key
2. Add Credentials
- Go to Jenkins → Manage Jenkins → Credentials
- Select appropriate scope
- Add Credentials:
- Kind: Secret text
- Secret: Your API key
- ID:
blocksecops-api-key - Description: BlockSecOps API Key
Declarative Pipeline
Create Jenkinsfile:
pipeline {
agent any
environment {
BLOCKSECOPS_API_KEY = credentials('blocksecops-api-key')
API_URL = 'https://api.blocksecops.com/api/v1'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Security Scan') {
steps {
script {
// Create archive
sh 'cd contracts && zip -r ../contracts.zip . && cd ..'
// Upload contract
def uploadResponse = sh(
script: """
curl -s -X POST "${API_URL}/contracts/upload" \
-H "Authorization: Bearer ${BLOCKSECOPS_API_KEY}" \
-F "[email protected]"
""",
returnStdout: true
).trim()
def contractId = readJSON(text: uploadResponse).id
// Start scan
def scanResponse = sh(
script: """
curl -s -X POST "${API_URL}/scans" \
-H "Authorization: Bearer ${BLOCKSECOPS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"contract_id": "${contractId}", "preset": "standard"}'
""",
returnStdout: true
).trim()
def scanId = readJSON(text: scanResponse).id
// Wait for completion
def status = ''
while (status != 'completed') {
sleep(15)
def statusResponse = sh(
script: """
curl -s "${API_URL}/scans/${scanId}" \
-H "Authorization: Bearer ${BLOCKSECOPS_API_KEY}"
""",
returnStdout: true
).trim()
status = readJSON(text: statusResponse).status
if (status == 'failed') {
error('Scan failed')
}
echo "Status: ${status}"
}
// Check results
def results = sh(
script: """
curl -s "${API_URL}/scans/${scanId}/results" \
-H "Authorization: Bearer ${BLOCKSECOPS_API_KEY}"
""",
returnStdout: true
).trim()
def summary = readJSON(text: results).summary
echo "Critical: ${summary.critical}, High: ${summary.high}"
if (summary.critical > 0) {
error("Found ${summary.critical} critical vulnerabilities!")
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: 'contracts.zip', fingerprint: true
}
}
}
Scripted Pipeline
node {
def apiKey = credentials('blocksecops-api-key')
def apiUrl = 'https://api.blocksecops.com/api/v1'
stage('Checkout') {
checkout scm
}
stage('Security Scan') {
// Create archive
sh 'cd contracts && zip -r ../contracts.zip . && cd ..'
// Upload and scan
def contractId = uploadContract(apiUrl, apiKey, 'contracts.zip')
def scanId = startScan(apiUrl, apiKey, contractId, 'standard')
// Wait
waitForScan(apiUrl, apiKey, scanId)
// Check results
def results = getResults(apiUrl, apiKey, scanId)
if (results.summary.critical > 0) {
error("Critical vulnerabilities found!")
}
}
}
def uploadContract(apiUrl, apiKey, file) {
def response = sh(
script: """
curl -s -X POST "${apiUrl}/contracts/upload" \
-H "Authorization: Bearer ${apiKey}" \
-F "file=@${file}"
""",
returnStdout: true
)
return readJSON(text: response).id
}
def startScan(apiUrl, apiKey, contractId, preset) {
def response = sh(
script: """
curl -s -X POST "${apiUrl}/scans" \
-H "Authorization: Bearer ${apiKey}" \
-H "Content-Type: application/json" \
-d '{"contract_id": "${contractId}", "preset": "${preset}"}'
""",
returnStdout: true
)
return readJSON(text: response).id
}
def waitForScan(apiUrl, apiKey, scanId) {
def status = ''
while (status != 'completed') {
sleep(15)
def response = sh(
script: """
curl -s "${apiUrl}/scans/${scanId}" \
-H "Authorization: Bearer ${apiKey}"
""",
returnStdout: true
)
status = readJSON(text: response).status
echo "Scan status: ${status}"
}
}
def getResults(apiUrl, apiKey, scanId) {
def response = sh(
script: """
curl -s "${apiUrl}/scans/${scanId}/results" \
-H "Authorization: Bearer ${apiKey}"
""",
returnStdout: true
)
return readJSON(text: response)
}
Shared Library
Create reusable steps in a shared library.
vars/blocksecops.groovy:
def scan(Map config) {
def apiKey = config.apiKey ?: credentials('blocksecops-api-key')
def preset = config.preset ?: 'standard'
def contractsPath = config.contractsPath ?: 'contracts'
def failOn = config.failOn ?: 'critical'
// Implementation...
}
Usage:
@Library('my-shared-library') _
pipeline {
stages {
stage('Security') {
steps {
blocksecops.scan(
contractsPath: 'src/contracts',
preset: 'deep',
failOn: 'high'
)
}
}
}
}
Multibranch Pipeline
Configure scanning per branch:
pipeline {
stages {
stage('Security Scan') {
steps {
script {
def preset = 'quick'
if (env.BRANCH_NAME == 'main') {
preset = 'deep'
} else if (env.BRANCH_NAME == 'develop') {
preset = 'standard'
}
// Run scan with preset
}
}
}
}
}
Parallel Scanning
Scan multiple projects:
stage('Security Scan') {
parallel {
stage('Token') {
steps {
blocksecops.scan(contractsPath: 'contracts/token')
}
}
stage('Vault') {
steps {
blocksecops.scan(contractsPath: 'contracts/vault')
}
}
}
}
Post Actions
post {
success {
echo 'Security scan passed!'
}
failure {
slackSend(
color: 'danger',
message: "Security scan failed: ${env.BUILD_URL}"
)
}
always {
// Archive results
archiveArtifacts artifacts: 'scan-results.json'
}
}
Troubleshooting
Credentials Not Found
- Check credential ID matches
- Verify credentials are in correct scope
- Check pipeline has access
JSON Parsing Errors
- Ensure
Pipeline Utility Stepsplugin installed - Check API responses for errors
Timeout
- Increase stage timeout
- Use async with webhooks for long scans
Next Steps
- Custom CI/CD - Other platforms
- API Overview - API reference
- Webhooks - Async notifications