Skip to content

Jenkins

Run Vulnetix in declarative and scripted Jenkins pipelines with credentials from the Jenkins store, gates, archived reports and catchError.

Updated 02 Nov 2026Checked against cli@24498404a

Credentials

Add two Secret text credentials, for example vulnetix-org-id and vulnetix-api-key. Bind them with withCredentials or environment { ... = credentials('...') }; Jenkins masks bound values in the console log.

Declarative pipeline

pipeline {
  agent any
  environment {
    VULNETIX_ORG_ID  = credentials('vulnetix-org-id')
    VULNETIX_API_KEY = credentials('vulnetix-api-key')
  }
  stages {
    stage('Install Vulnetix') {
      steps {
        sh 'curl -fsSL https://cli.vulnetix.com/install.sh | sh -s -- --install-dir "$HOME/.local/bin"'
        sh '"$HOME/.local/bin/vulnetix" auth verify'
      }
    }
    stage('Scan') {
      steps {
        sh 'mkdir -p dist && "$HOME/.local/bin/vulnetix" scan --fail-on high -o dist/sbom.cdx.json -o dist/results.sarif'
      }
    }
  }
  post {
    always {
      archiveArtifacts artifacts: 'dist/**', allowEmptyArchive: true
    }
  }
}

Each sh step is a new shell, so the steps call the binary by its full path. allowEmptyArchive: true covers the clean case, where no SARIF file is written.

Report without failing

    stage('Scan') {
      steps {
        catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
          sh '"$HOME/.local/bin/vulnetix" scan --fail-on high'
        }
      }
    }

To treat an undecided jail gate (exit 3) differently from a breach (exit 1):

script {
  def code = sh(script: '"$HOME/.local/bin/vulnetix" scan --fail-on high --jail', returnStatus: true)
  if (code == 3) { unstable('jail could not decide: check the required scans ran') }
  else if (code != 0) { error("Vulnetix gate failed (exit ${code})") }
}

Scripted pipeline

node {
  checkout scm
  withCredentials([
    string(credentialsId: 'vulnetix-org-id', variable: 'VULNETIX_ORG_ID'),
    string(credentialsId: 'vulnetix-api-key', variable: 'VULNETIX_API_KEY'),
  ]) {
    withEnv(["PATH+VULNETIX=${env.HOME}/.local/bin"]) {
      sh 'curl -fsSL https://cli.vulnetix.com/install.sh | sh -s -- --install-dir "$HOME/.local/bin"'
      sh 'vulnetix auth verify'
      sh 'vulnetix scan --fail-on high,kev'
    }
  }
}

Use single-quoted sh strings so the shell, not Groovy, expands the secret variables; Groovy interpolation of a secret puts it in the build’s command line.

Pipeline context

The CLI detects Jenkins from JENKINS_URL or BUILD_NUMBER, and reads GIT_URL, GIT_COMMIT, GIT_BRANCH, CHANGE_BRANCH, CHANGE_TARGET, BUILD_ID, BUILD_NUMBER, JOB_NAME, WORKSPACE and NODE_LABELS. GIT_* are set by the Git plugin’s checkout; without them the CLI reads the local checkout.

Agents in containers

With agent { docker { image 'alpine:3.20' } }, install curl and ca-certificates first (apk add --no-cache curl ca-certificates git), or use an image of your own with the CLI baked in; see Containers.

Edit this pageSources: cli/internal/config/config.go, cli/install.sh, cli/cmd/scan.go
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.