This Jenkins shared library facilitates the integration of Ethiack's Public API (API docs) for launching scans through Jenkins pipelines. By using this library, you can seamlessly incorporate Ethiack's security scanning capabilities into your Jenkins workflows, enhancing your CI/CD pipeline with automated security testing.
Note
For more information on these and other installation methods, please refer to the Jenkins' extensive documentation on shared libraries.
Method #1: Using Global Shared Libraries (Recommended)
-
Navigate to
Dashboard » Manage Jenkins » System » Global Pipeline Librarieson the Jenkins dashboard. -
Under the Global Pipeline Libraries section, provide the following configuration:
Name:
ethiack-library
Default Version:main
Load implicitly: ☐
Allow default version to be overridden: ☑
Include @Library changes in job recent changes: ☑
Cache fetched versions on controller for quick retrieval: ☐Retrieval Method:
Modern SCMSource Code Management:
GitProject Repository:
https://github.com/ethiack/jenkins-libraryCredentials:- none -Fresh clone per build: ☑
The shared library can then be imported in a pipeline with:
@Library("ethiack-library") _Method #2: Using the Github Groovy Libraries plugin
The Github Groovy Libraries plugin allows pipelines to be loaded on the fly from GitHub repositories. If the plugin is installed, simply import the library repository in the working pipeline:
@Library('github.com/ethiack/jenkins-library@main') _Using Ethiack's API - and, therefore, this shared library - requires authentication using an API Key and API Secret, which can be retrieved in Ethiack's Portal settings page. These credentials must be available as environment variables ETHIACK_API_KEY and ETHIACK_API_SECRET, repectively, whenever the shared library is used.
To setup these credentials in Jenkins:
- Navigate to
Dashboard » Manage Jenkins » Credentialson the Jenkins homepage. - Select the desired store/domain
- Add API Key:
New Credential
Kind:
Secret TextSecret: [YOUR API KEY]
ID:ethiack-api-key
Description: Optional - Add API Secret:
New Credential
Kind:
Secret TextSecret: [YOUR API SECRET]
ID:ethiack-api-secret
Description: Optional
Caution
Ensure that the store/domain used for storing the API Key and the API Secret has an adequate scope and access rules.
Note
For more information, see https://www.jenkins.io/doc/book/using/using-credentials/.
Note
This shared library is fundamentally a wrapper around Ethiack's Public API. For more information, see the API docs.
This pipeline launches a scan for the domain https://example.ethiack.com and waits until it finishes.
@Library("ethiack-library")_
import groovy.json.JsonSlurper
pipeline {
agent any
environment {
ETHIACK_API_KEY = credentials('ethiack-api-key')
ETHIACK_API_SECRET = credentials('ethiack-api-secret')
}
stages {
stage('Ethiack Scan') {
steps {
script {
def job = ethiack.launchJob("https://example.ethiack.com:443")
def resp = ethiack.awaitJob(job.uuid, Severity.MEDIUM, false)
def job_info = ethiack.getJobInfo(job.uuid)
println job_info
if(resp.success == false) {
error(resp.message)
}
}
}
}
}
}This example demonstrates how to use the optional parameters for tracking and integration purposes.
@Library("ethiack-library")_
import groovy.json.JsonSlurper
pipeline {
agent any
environment {
ETHIACK_API_KEY = credentials('ethiack-api-key')
ETHIACK_API_SECRET = credentials('ethiack-api-secret')
}
stages {
stage('Ethiack Scan') {
steps {
script {
def buildNumber = env.BUILD_NUMBER.toInteger()
def releaseVersion = "v1.2.3"
// Launch a scan with tracking information
def job = ethiack.launchJob(
"https://example.ethiack.com:443",
buildNumber, // beacon_id for build tracking
"release-${releaseVersion}" // event_slug for release tracking
)
def resp = ethiack.awaitJob(job.uuid, Severity.MEDIUM, false)
if(resp.success == false) {
error(resp.message)
}
}
}
}
}
}A complete list of the available commands is provided below.
Description: Check if the provided URL is valid and the scan is authorized for the organization.
Signature:
Boolean check(String url, Integer beacon_id = null, String event_slug = null, Boolean failOnBadStatus = false) {...}Parameters:
url: URL to checkbeacon_id: Optional beacon ID to associate with the checkevent_slug: Optional event slug to associate with the checkfailOnBadStatus: If true, an error will be raised if the operation failsReturns:
truetrue if URL is valid and if the organization has scan minutes available,falseotherwise
Description: Launch a new job for the provided URL if the provided URL is valid and the organization has scan minutes available.
Signature:
Map launchJob(String url, Integer beacon_id = null, String event_slug = null, Boolean failOnBadStatus = true) {...}Parameters:
url: URL to scan.beacon_id: Optional beacon ID to associate with the jobevent_slug: Optional event slug to associate with the jobfailOnBadStatus: Iftrue, an error will be raised if the operation failsReturns:
- Map object with the information about the launched job
Description: Cancel a job. The status of the job will be changed to
CANCELED.Signature:
void cancelJob(String jobUuid, Boolean failOnBadStatus = true) {...}Parameters:
jobUuid: UUID of job to cancelfailOnBadStatus: Iftrue, an error will be raised if the operation fails
Description: Get a list of jobs for the current organization.
Signature:
Map listJobs(Boolean failOnBadStatus = true) {...}Parameters:
failOnBadStatus: Iftrue, an error will be raised if the operation failsReturns:
- List of jobs
Description: Get job information, containing the status and a list of findings for the requested job UUID.
Signature:
Map getJobInfo(String jobUuid, Boolean failOnBadStatus = true) {...}Parameters:
jobUuid: UUID of the jobfailOnBadStatus: Iftrue, an error will be raised if the operation failsReturns:
- Map object with info about the job's information and its findings
Description: Get job status of the requested job UUID.
Signature:
String getJobStatus(String jobUuid, Boolean failOnBadStatus = true) {...}Parameters:
jobUuid: UUID of the jobfailOnBadStatus: Iftrue, an error will be raised if the operation failsReturns:
- Job status. One of:
PENDING,IN_PROGRESS,FINISHED,ERROR,CANCELED
Description: Get job success status. A job is considered unsucessful if it contains findings with a greater or equal severity to the one provided.
Signature:
Map getJobSuccess(String jobUuid, String severity = null, Boolean failOnBadStatus = true) {...}Parameters:
jobUuid: UUID of the jobseverity: Minimum severity of findings for which an error should be raised. Defaults to medium.failOnBadStatus: Iftrue, an error will be raised if the operation failsReturns:
- Map object with job success status and message
Description: Wait for the job to complete. The success of the job will be queried until it finishes or fails, or the job timeout is reached.
Signature:
Map awaitJob(String jobUuid, Integer timeout = 3600, String severity = null, Boolean quiet = true, Boolean failOnBadStatus = true) {...}Parameters:
jobUuid: UUID of the jobtimeout: Timeout in seconds to wait for job to completeseverity: Minimum severity of findings for which an error should be raisedquiet: Iftrue, retry information won't be echoedfailOnBadStatus: Fftrue, an error will be raised if the operation failsReturns:
- Map object with job success status and message
Distributed under the MIT License. See LICENSE for more information.
