Anchore Enterprise can be integrated into Jenkins pipelines to generate and analyze SBOMs, perform vulnerability scanning, and enforce policy evaluation as a pipeline gate.
Configure Variables
Before getting started, you need to configure your Jenkins instance with the required credentials. Make sure the following values are added under Dashboard → Manage Jenkins → Credentials as credentials of type Secret text:
ANCHORECTL_USERNAME
ANCHORECTL_PASSWORD
ANCHORECTL_URL
These are necessary for the integration to access your Anchore Enterprise deployment. The ANCHORECTL_PASSWORD value should be created as a repository secret to prevent exposure of the value in job logs, while ANCHORECTL_URL and ANCHORECTL_USERNAME can be created as repository variables.

Add a Pipeline Example to Jenkins
Each groovy block below is a complete declarative pipeline. Use one as a starting point in either of the following ways:
- Pipeline script. Create or open a Jenkins Pipeline job, then under Pipeline → Definition select Pipeline script and paste the example directly into the script text area.
- Pipeline script from SCM. Save the example as a
Jenkinsfilein your repository, then under Pipeline → Definition select Pipeline script from SCM, point it at that repository, and set the Script Path to the file’s location (Jenkinsfileat the repository root by default).
Either way, the parameters block at the top of each example (REGISTRY, APP_NAME, and so on) surfaces as build-time inputs on the job’s Build with Parameters page, so you don’t need to edit the script to point it at a different image or app version.
Configure Scanning Mode
Anchore Enterprise exposes two scopes for scanning and policy evaluation. Pick the one that matches how your team organizes software.
| Scope | What is scanned | Typical use |
|---|---|---|
| App-Scoped | Every asset attached to an app version — container images, analyzed filesystems, or externally supplied SBOMs | Aggregated, deduplicated vulnerability and policy results across an app version; the v6-native path |
| Image-Scoped | A single container image, identified by digest | Ad-hoc image checks, image-stage CI gates, and any workflow that has not yet adopted the apps, versions, and assets model |
App-Scoped Pipelines
You can also manage apps, versions, and assets directly from your pipeline. The pipeline creates or reuses an app and an app version, attaches the build output to the version as an asset, and performs the analysis. See Managing Assets in an App Version to learn more about apps.
anchorectl app commands require Anchore Enterprise and AnchoreCTL v6.0.0 or later. For the full command reference, see Creating and Managing Apps.Bring Your Own SBOM (BYOS) Asset
This pipeline creates or reuses an app and an app version, then uploads an existing SBOM — from a vendor, a different SCA tool, AnchoreCTL/Syft, or an earlier stage in this same pipeline — and attaches it to the version as an asset, before reporting vulnerabilities and evaluating policy for the app version.
pipeline {
agent any
// Define parameters for user input
parameters {
string(name: 'APP_NAME', defaultValue: 'storefront', description: 'The app to attach the SBOM to.', trim: true)
string(name: 'APP_VERSION', defaultValue: '1.0.0', description: 'The app version to update.', trim: true)
string(name: 'SBOM_FILE', defaultValue: 'sbom.json', description: 'Path to an existing SBOM file to upload.', trim: true)
choice(name: 'ANCHORECTL_QUIET', choices: ['true', 'false'], description: 'Suppress anchorectl informational messages.')
choice(name: 'ANCHORECTL_FAIL_BASED_ON_RESULTS', choices: ['true', 'false'], description: 'How to handle fail signals (e.g., policy check outcomes)')
}
stages {
stage('Anchore App Update') {
environment {
// This is the AnchoreCTL service endpoint (fetched securely from Jenkins credentials)
ANCHORECTL_URL = credentials('ANCHORECTL_URL')
// Define the Anchore account username
ANCHORECTL_USERNAME = credentials('ANCHORECTL_USERNAME')
// Define the Anchore account password
ANCHORECTL_PASSWORD = credentials('ANCHORECTL_PASSWORD')
// Whether to fail the pipeline based on the app version policy evaluation (controlled by Jenkins parameter)
ANCHORECTL_FAIL_BASED_ON_RESULTS = "${params.ANCHORECTL_FAIL_BASED_ON_RESULTS}"
// You can also choose to Suppress unnecessary output logs
ANCHORECTL_QUIET = "${params.ANCHORECTL_QUIET}"
// Make the downloaded anchorectl binary available to every step
PATH = "${env.HOME}/.local/bin:${env.PATH}"
}
steps {
script {
echo 'Starting app version update pipeline.'
// Download and configure the Anchore CLI
sh 'mkdir -p $HOME/.local/bin && curl -sSfL "${ANCHORECTL_URL%/}/v2/system/anchorectl?operating_system=linux&architecture=amd64" -H "accept: */*" | tar -zx -C $HOME/.local/bin anchorectl'
// Create the app if it does not exist yet
sh "anchorectl app get '${params.APP_NAME}' -o id > /dev/null 2>&1 || anchorectl app add '${params.APP_NAME}' --contact-name 'Platform Team'"
// Create the app version if it does not exist yet
sh "anchorectl app version get '${params.APP_VERSION}' --app '${params.APP_NAME}' -o id > /dev/null 2>&1 || anchorectl app version add '${params.APP_VERSION}' --app '${params.APP_NAME}' --status in_progress"
// Upload the existing SBOM and attach it to the app version as an asset
sh "anchorectl app version asset add sbom '${params.SBOM_FILE}' --app '${params.APP_NAME}' --version '${params.APP_VERSION}' --asset '${params.SBOM_FILE}' --wait"
// Retrieve and archive the vulnerability report for the app version
sh "anchorectl app version vuln list '${params.APP_VERSION}' --app '${params.APP_NAME}' | tee app-vulnerabilities.txt"
archiveArtifacts artifacts: 'app-vulnerabilities.txt'
// Run and archive the app version policy evaluation (fails the build when ANCHORECTL_FAIL_BASED_ON_RESULTS is true and the evaluation result is 'fail')
sh """#!/bin/bash
set -o pipefail
anchorectl app version policy status get '${params.APP_VERSION}' --app '${params.APP_NAME}' | tee app-policy-status.txt
"""
archiveArtifacts artifacts: 'app-policy-status.txt'
}
}
}
}
}
Container Image Asset
To attach a container image instead of an SBOM file, keep the same app/app-version creation, vulnerability retrieval, and policy evaluation steps as the BYOS example above, and swap only the parameters and the asset-add step:
- Replace the
SBOM_FILEparameter with image parameters (REGISTRY,REPOSITORY,TAG), as in the Image-Scoped Pipelines examples. - Replace the asset-add step with the
container-imageasset type, which has AnchoreCTL scan the image before attaching it:
// Scan the image and attach it to the app version as an asset
sh "anchorectl app version asset add container-image '${params.REGISTRY}/${params.REPOSITORY}:${params.TAG}' --app '${params.APP_NAME}' --version '${params.APP_VERSION}' --asset '${params.REPOSITORY}:${params.TAG}' --wait"
Image-Scoped Pipelines
Below are examples of the types of image scans. For a detailed explanation of their differences, refer to the Images concept page.
Distributed
This is the most easily scalable method for scanning images. Distributed scanning uses the anchorectl utility to build the SBOM directly on the build runner and then pushes the SBOM to Anchore Enterprise through the API. The example below demonstrates how to automate distributed analysis within a pipeline.
pipeline {
// Define parameters for user input
parameters {
string(name: 'REGISTRY', defaultValue: 'docker.io', description: 'The container registry to use.', trim: true)
string(name: 'REPOSITORY', defaultValue: 'library/nginx', description: 'The image repository path.', trim: true)
string(name: 'TAG', defaultValue: 'latest', description: 'The image tag to analyze.', trim: true)
choice(name: 'ANCHORECTL_QUIET', choices: ['true', 'false'], description: 'Suppress anchorectl informational messages.')
choice(name: 'ANCHORECTL_FORMAT', choices: ['json', 'csv'], description: 'The output format for anchorectl (e.g., json, csv).')
choice(name: 'ANCHORECTL_FAIL_BASED_ON_RESULTS', choices: ['true', 'false'], description: 'How to handle fail signals (e.g., policy check outcomes)')
}
stages {
stage('Anchore Image Scan') {
environment {
// This is the AnchoreCTL service endpoint (fetched securely from Jenkins credentials)
ANCHORECTL_URL = credentials('ANCHORECTL_URL')
// Define the Anchore account username
ANCHORECTL_USERNAME = credentials('ANCHORECTL_USERNAME')
// Define the Anchore account password
ANCHORECTL_PASSWORD = credentials('ANCHORECTL_PASSWORD')
// Whether to fail the pipeline based on AnchoreCTL scan results (controlled by Jenkins parameter)
ANCHORECTL_FAIL_BASED_ON_RESULTS = "${params.ANCHORECTL_FAIL_BASED_ON_RESULTS}"
// You can also choose to Suppress unnecessary output logs
ANCHORECTL_QUIET = "${params.ANCHORECTL_QUIET}"
// Define the Output format for AnchoreCTL results
ANCHORECTL_FORMAT = "${params.ANCHORECTL_FORMAT}"
// Make the downloaded anchorectl binary available to every step
PATH = "${env.HOME}/.local/bin:${env.PATH}"
}
steps {
script {
echo 'Starting image analysis pipeline.'
// Download and configure the Anchore CLI
sh 'mkdir -p $HOME/.local/bin && curl -sSfL "${ANCHORECTL_URL%/}/v2/system/anchorectl?operating_system=linux&architecture=amd64" -H "accept: */*" | tar -zx -C $HOME/.local/bin anchorectl'
// Add the image to Anchore and wait for analysis to complete
sh "anchorectl image add --wait --from registry ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG}"
// Retrieve and archive vulnerability report
sh "anchorectl image vulnerabilities ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG} | tee vulnerabilities.${ANCHORECTL_FORMAT}"
archiveArtifacts artifacts: "vulnerabilities.${env.ANCHORECTL_FORMAT}"
// Run and archive the policy check
sh """#!/bin/bash
set -o pipefail
anchorectl image check --detail ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG} | tee policy-check.${ANCHORECTL_FORMAT}
"""
archiveArtifacts artifacts: "policy-check.${env.ANCHORECTL_FORMAT}"
// Post-build action to handle policy failure, if configured
if (env.ANCHORECTL_FAIL_BASED_ON_RESULTS == 'true') {
def policyCheckResult = sh(script: "grep -q 'Policy Evaluation: PASS' policy-check.${ANCHORECTL_FORMAT}", returnStatus: true)
if (policyCheckResult != 0) {
error('Policy check failed based on results.')
}
}
}
}
}
}
}
Centralized
Centralized Scanning uses analyzer pods in Anchore Enterprise to generate the SBOM. This method is ideal when the operator does not control the image build process, supports asynchronous scanning, and is required for malware detection through ClamAV. After your container image is built, you can trigger a scan by adding the provided stage to your pipeline, which will instruct Anchore Enterprise to analyze the image and display vulnerability and policy results in the build log. Below is an example of how to achieve centralized scanning in your pipeline
pipeline {
// Define parameters for user input
parameters {
string(name: 'REGISTRY', defaultValue: 'docker.io', description: 'The container registry to use.', trim: true)
string(name: 'REPOSITORY', defaultValue: 'library/nginx', description: 'The image repository path.', trim: true)
string(name: 'TAG', defaultValue: 'latest', description: 'The image tag to analyze.', trim: true)
choice(name: 'ANCHORECTL_QUIET', choices: ['true', 'false'], description: 'Suppress anchorectl informational messages.')
choice(name: 'ANCHORECTL_FORMAT', choices: ['json', 'csv'], description: 'The output format for anchorectl (e.g., json, csv).')
choice(name: 'ANCHORECTL_FAIL_BASED_ON_RESULTS', choices: ['true', 'false'], description: 'How to handle fail signals (e.g., policy check outcomes)')
}
stages {
stage('Anchore Image Scan') {
environment {
// This is the AnchoreCTL service endpoint (fetched securely from Jenkins credentials)
ANCHORECTL_URL = credentials('ANCHORECTL_URL')
// Define the Anchore account username
ANCHORECTL_USERNAME = credentials('ANCHORECTL_USERNAME')
// Define the Anchore account password
ANCHORECTL_PASSWORD = credentials('ANCHORECTL_PASSWORD')
// Whether to fail the pipeline based on AnchoreCTL scan results (controlled by Jenkins parameter)
ANCHORECTL_FAIL_BASED_ON_RESULTS = "${params.ANCHORECTL_FAIL_BASED_ON_RESULTS}"
// You can also choose to Suppress unnecessary output logs
ANCHORECTL_QUIET = "${params.ANCHORECTL_QUIET}"
// Define the Output format for AnchoreCTL results
ANCHORECTL_FORMAT = "${params.ANCHORECTL_FORMAT}"
// Make the downloaded anchorectl binary available to every step
PATH = "${env.HOME}/.local/bin:${env.PATH}"
}
steps {
script {
echo "Starting image analysis for: ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG}"
// Download and configure the Anchore CLI
sh 'mkdir -p $HOME/.local/bin && curl -sSfL "${ANCHORECTL_URL%/}/v2/system/anchorectl?operating_system=linux&architecture=amd64" -H "accept: */*" | tar -zx -C $HOME/.local/bin anchorectl'
// Add the image to Anchore and wait for analysis to complete
sh "anchorectl image add --wait ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG}"
// Retrieve and archive vulnerability report
sh "anchorectl image vulnerabilities ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG} | tee vulnerabilities.${ANCHORECTL_FORMAT}"
archiveArtifacts artifacts: "vulnerabilities.${env.ANCHORECTL_FORMAT}"
// Run and archive the policy check
sh """#!/bin/bash
set -o pipefail
anchorectl image check --detail ${params.REGISTRY}/${params.REPOSITORY}:${params.TAG} | tee policy-check.${ANCHORECTL_FORMAT}
"""
archiveArtifacts artifacts: "policy-check.${env.ANCHORECTL_FORMAT}"
// Post-build action to handle policy failure, if configured
if (env.ANCHORECTL_FAIL_BASED_ON_RESULTS == 'true') {
def policyCheckResult = sh(script: "grep -q 'Policy Evaluation: PASS' policy-check.${ANCHORECTL_FORMAT}", returnStatus: true)
if (policyCheckResult != 0) {
error('Policy check failed based on results.')
}
}
}
}
}
}
}
One-Time Scan
Use anchorectl image one-time-scan to analyze an image against Anchore Enterprise policies without adding it to the image inventory or persisting its SBOM — a stateless variant of distributed analysis suited to CI pipelines that want fast pass/fail feedback. See One-Time Scan for the underlying mechanics.
pipeline {
agent any
stages {
stage('Anchore One-Time Scan') {
environment {
ANCHORECTL_URL = credentials('ANCHORECTL_URL')
ANCHORECTL_USERNAME = credentials('ANCHORECTL_USERNAME')
ANCHORECTL_PASSWORD = credentials('ANCHORECTL_PASSWORD')
// Make the downloaded anchorectl binary available to every step
PATH = "${env.HOME}/.local/bin:${env.PATH}"
}
steps {
script {
sh 'mkdir -p $HOME/.local/bin && curl -sSfL "${ANCHORECTL_URL%/}/v2/system/anchorectl?operating_system=linux&architecture=amd64" -H "accept: */*" | tar -zx -C $HOME/.local/bin anchorectl'
sh 'anchorectl image one-time-scan -o json docker.io/library/nginx:latest | tee vulnerabilities.json'
}
}
}
}
}
Visualize Vulnerabilities with the Warnings NG Plugin
The Jenkins Warnings Next Generation plugin (warnings-ng) can parse anchorectl vulnerability output and surface findings as tracked issues directly in the Jenkins UI — complete with trend graphs, per-build issue counts, and configurable quality gates.
pattern parameter shown in each example below.Prerequisites
- Jenkins Warnings Next Generation plugin installed (Manage Jenkins → Plugins → Available plugins, search for “Warnings Next Generation”)
anchorectlavailable on the build runner (see Configure Variables above)
Supported Output Variants
The anchorectl() tool scans for files matching **/*vulnerabilities*.json and transparently handles all of the following output formats:
| Command | Output Format |
|---|---|
anchorectl app version vuln list VERSION --app APP -o json | Aggregated, deduplicated vulnerability list for an app version |
anchorectl image one-time-scan -o json IMAGE | Single unified envelope (sbom, policyEvaluation, and vulnerabilities in one file) |
anchorectl image one-time-scan -o json --output-directory DIR IMAGE | Standalone *_vulnerabilities.json file (camelCase keys) |
anchorectl image one-time-scan -o json-raw --output-directory DIR IMAGE | Standalone *_vulnerabilities.json file (snake_case keys) |
anchorectl image vulnerabilities -o json IMAGE > *_vulnerabilities.json | Vulnerability report (camelCase keys) from a previously analyzed image |
anchorectl image vulnerabilities -o json-raw IMAGE > *_vulnerabilities.json | Vulnerability report (snake_case keys) from a previously analyzed image |
App Version Vuln List
Use anchorectl app version vuln list to visualize the aggregated, deduplicated vulnerability list for an app version — across every asset attached to it. This assumes the app version already has assets attached; see App-Scoped Pipelines above.
pipeline {
agent any
// Define parameters for user input
parameters {
string(name: 'APP_NAME', defaultValue: 'storefront', description: 'The app to report on.', trim: true)
string(name: 'APP_VERSION', defaultValue: '1.0.0', description: 'The app version to report on.', trim: true)
}
stages {
stage('Anchore App Version Vuln List') {
environment {
ANCHORECTL_URL = credentials('ANCHORECTL_URL')
ANCHORECTL_USERNAME = credentials('ANCHORECTL_USERNAME')
ANCHORECTL_PASSWORD = credentials('ANCHORECTL_PASSWORD')
// Make the downloaded anchorectl binary available to every step
PATH = "${env.HOME}/.local/bin:${env.PATH}"
}
steps {
script {
sh 'mkdir -p $HOME/.local/bin && curl -sSfL "${ANCHORECTL_URL%/}/v2/system/anchorectl?operating_system=linux&architecture=amd64" -H "accept: */*" | tar -zx -C $HOME/.local/bin anchorectl'
sh "anchorectl app version vuln list '${params.APP_VERSION}' --app '${params.APP_NAME}' -o json | tee app_vulnerabilities.json"
}
}
}
}
post {
always {
recordIssues(tools: [anchorectl(pattern: 'app_vulnerabilities.json')])
}
}
}

Image Add and Vulnerabilities
Use anchorectl image add to submit an image to Anchore Enterprise for centralized analysis. Once analysis is complete, retrieve the vulnerability report with anchorectl image vulnerabilities and save it to a file the plugin can detect.
pipeline {
agent any
stages {
stage('Anchore Image Scan') {
environment {
ANCHORECTL_URL = credentials('ANCHORECTL_URL')
ANCHORECTL_USERNAME = credentials('ANCHORECTL_USERNAME')
ANCHORECTL_PASSWORD = credentials('ANCHORECTL_PASSWORD')
// Make the downloaded anchorectl binary available to every step
PATH = "${env.HOME}/.local/bin:${env.PATH}"
}
steps {
script {
sh 'mkdir -p $HOME/.local/bin && curl -sSfL "${ANCHORECTL_URL%/}/v2/system/anchorectl?operating_system=linux&architecture=amd64" -H "accept: */*" | tar -zx -C $HOME/.local/bin anchorectl'
sh 'anchorectl image add --wait docker.io/library/nginx:latest'
sh 'anchorectl image vulnerabilities -o json docker.io/library/nginx:latest > image_vulnerabilities.json'
}
}
}
}
post {
always {
recordIssues(tools: [anchorectl(pattern: 'image_vulnerabilities.json')])
}
}
}

Severity Mapping
Anchore severity levels are mapped to Jenkins issue severities as follows:
| Anchore Severity | Jenkins Severity |
|---|---|
| Critical | ERROR |
| High | WARNING_HIGH |
| Medium | WARNING_NORMAL |
| Low, Negligible | WARNING_LOW |
qualityGates parameter to the recordIssues step. See the Warnings NG plugin documentation for details.