Custom Cicd

Integrate BlockSecOps with any CI/CD platform. Any CI/CD system can integrate with BlockSecOps using: - REST API for all operations - Webhooks for async...

Last updated: January 14, 2026

Custom CI/CD Integration

Integrate BlockSecOps with any CI/CD platform.

Overview

Any CI/CD system can integrate with BlockSecOps using:

  • REST API for all operations
  • Webhooks for async notifications
  • Standard HTTP tools (curl, wget)

Integration Steps

1. Prepare

  • Create API key
  • Store key as CI secret
  • Install curl or similar HTTP client

2. Upload Contract

CONTRACT_RESPONSE=$(curl -s -X POST \
  "https://api.blocksecops.com/api/v1/contracts/upload" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY" \
  -F "[email protected]")

CONTRACT_ID=$(echo $CONTRACT_RESPONSE | jq -r '.id')

3. Start Scan

SCAN_RESPONSE=$(curl -s -X POST \
  "https://api.blocksecops.com/api/v1/scans" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"contract_id\": \"$CONTRACT_ID\", \"preset\": \"standard\"}")

SCAN_ID=$(echo $SCAN_RESPONSE | jq -r '.id')

4. Wait for Completion

while true; do
  STATUS=$(curl -s \
    "https://api.blocksecops.com/api/v1/scans/$SCAN_ID" \
    -H "Authorization: Bearer $BLOCKSECOPS_API_KEY" \
    | jq -r '.status')

  if [ "$STATUS" = "completed" ]; then
    break
  elif [ "$STATUS" = "failed" ]; then
    echo "Scan failed"
    exit 1
  fi

  echo "Waiting... ($STATUS)"
  sleep 15
done

5. Check Results

RESULTS=$(curl -s \
  "https://api.blocksecops.com/api/v1/scans/$SCAN_ID/results" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY")

CRITICAL=$(echo $RESULTS | jq '.summary.critical')
HIGH=$(echo $RESULTS | jq '.summary.high')

if [ "$CRITICAL" -gt 0 ]; then
  echo "Critical vulnerabilities found!"
  exit 1
fi

if [ "$HIGH" -gt 0 ]; then
  echo "Warning: High vulnerabilities found"
fi

echo "Scan passed"

Complete Script

#!/bin/bash
set -e

# Configuration
API_URL="https://api.blocksecops.com/api/v1"
CONTRACTS_PATH="${1:-contracts}"
PRESET="${2:-standard}"
FAIL_ON="${3:-critical}"

# Check API key
if [ -z "$BLOCKSECOPS_API_KEY" ]; then
  echo "Error: BLOCKSECOPS_API_KEY not set"
  exit 1
fi

# Create archive
echo "Creating archive..."
ARCHIVE=$(mktemp -u).zip
(cd "$CONTRACTS_PATH" && zip -r "$ARCHIVE" .)

# Upload
echo "Uploading..."
UPLOAD_RESPONSE=$(curl -s -X POST "$API_URL/contracts/upload" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY" \
  -F "file=@$ARCHIVE")

CONTRACT_ID=$(echo $UPLOAD_RESPONSE | jq -r '.id')
if [ "$CONTRACT_ID" = "null" ]; then
  echo "Upload failed: $UPLOAD_RESPONSE"
  exit 1
fi
echo "Contract ID: $CONTRACT_ID"

# Start scan
echo "Starting scan..."
SCAN_RESPONSE=$(curl -s -X POST "$API_URL/scans" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"contract_id\": \"$CONTRACT_ID\", \"preset\": \"$PRESET\"}")

SCAN_ID=$(echo $SCAN_RESPONSE | jq -r '.id')
echo "Scan ID: $SCAN_ID"

# Wait
echo "Waiting for scan..."
while true; do
  STATUS_RESPONSE=$(curl -s "$API_URL/scans/$SCAN_ID" \
    -H "Authorization: Bearer $BLOCKSECOPS_API_KEY")
  STATUS=$(echo $STATUS_RESPONSE | jq -r '.status')

  case "$STATUS" in
    completed)
      echo "Scan completed"
      break
      ;;
    failed)
      echo "Scan failed"
      exit 1
      ;;
    *)
      echo "Status: $STATUS"
      sleep 15
      ;;
  esac
done

# Get results
RESULTS=$(curl -s "$API_URL/scans/$SCAN_ID/results" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY")

CRITICAL=$(echo $RESULTS | jq '.summary.critical')
HIGH=$(echo $RESULTS | jq '.summary.high')
MEDIUM=$(echo $RESULTS | jq '.summary.medium')
LOW=$(echo $RESULTS | jq '.summary.low')

echo ""
echo "=== Results ==="
echo "Critical: $CRITICAL"
echo "High: $HIGH"
echo "Medium: $MEDIUM"
echo "Low: $LOW"
echo "==============="
echo ""

# Check thresholds
case "$FAIL_ON" in
  critical)
    if [ "$CRITICAL" -gt 0 ]; then
      echo "FAILED: $CRITICAL critical vulnerabilities"
      exit 1
    fi
    ;;
  high)
    if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
      echo "FAILED: $CRITICAL critical, $HIGH high vulnerabilities"
      exit 1
    fi
    ;;
  medium)
    if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ] || [ "$MEDIUM" -gt 0 ]; then
      echo "FAILED: Found critical/high/medium vulnerabilities"
      exit 1
    fi
    ;;
esac

echo "PASSED"
rm -f "$ARCHIVE"

Platform Examples

CircleCI

version: 2.1

jobs:
  security-scan:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: |
            sudo apt-get update
            sudo apt-get install -y jq zip
      - run:
          name: Security scan
          command: |
            ./scripts/blocksecops-scan.sh contracts standard critical

workflows:
  main:
    jobs:
      - security-scan

Azure DevOps

trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

steps:
  - task: Bash@3
    env:
      BLOCKSECOPS_API_KEY: $(BLOCKSECOPS_API_KEY)
    inputs:
      targetType: 'filePath'
      filePath: './scripts/blocksecops-scan.sh'
      arguments: 'contracts standard critical'

Bitbucket Pipelines

pipelines:
  default:
    - step:
        name: Security Scan
        script:
          - apt-get update && apt-get install -y jq zip
          - ./scripts/blocksecops-scan.sh contracts standard critical

Travis CI

language: minimal

script:
  - ./scripts/blocksecops-scan.sh contracts standard critical

env:
  global:
    - secure: "encrypted_api_key"

Async with Webhooks

For long scans, use webhooks instead of polling:

  1. Set up webhook endpoint
  2. Start scan with callback URL
  3. Wait for webhook notification
  4. Continue pipeline
# Start scan with webhook
curl -X POST "$API_URL/scans" \
  -H "Authorization: Bearer $BLOCKSECOPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contract_id": "'$CONTRACT_ID'",
    "preset": "deep",
    "webhook_url": "'$CALLBACK_URL'"
  }'

Best Practices

Secret Management

  • Never commit API keys
  • Use CI secret storage
  • Rotate keys periodically

Error Handling

  • Check all curl responses
  • Handle network timeouts
  • Log failures clearly

Performance

  • Use quick preset for PRs
  • Cache when code unchanged
  • Consider async for deep scans

Next Steps