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

  1. Go to BlockSecOps SettingsAPI Keys
  2. Click Create Key
  3. Name: "Jenkins"
  4. Copy the key

2. Add Credentials

  1. Go to Jenkins → Manage Jenkins → Credentials
  2. Select appropriate scope
  3. 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 Steps plugin installed
  • Check API responses for errors

Timeout

  • Increase stage timeout
  • Use async with webhooks for long scans

Next Steps