Integrating Scribe in your Jenkins pipeline
If you are using Jenkins as your Continuous Integration tool (CI), use these instructions to integrate Scribe into your pipeline to protect your projects.
Before you begin
Acquiring credentials from Scribe Hub
Integrating Scribe Hub with Jenkins requires the following credentials that are found in the product setup dialog. (In your Scribe Hub go to Home>Products>[$product]>Setup)
- Product Key
- Client ID
- Client Secret
Note that the product key is unique per product, while the client ID and secret are unique for your account.
Adding Credentials to Jenkins
Go to your Jenkins Web Console.
Select Dashboard> Manage Jenkins> Manage credentials (under Security options).
Go to the Global Credential setup: click on any one of the clickable Global Domains in the Domain column.
To add global credentials, in the Global credentials area, click + Add Credentials. A new Credentials form opens.
To add the Product Key, in the Kind field, select Secret Text.
Copy the Product Key provided by Scribe to the Secret field.
Set the ID as scribe-product-key (lowercase).
Leave Scope as Global.
Add a helpful Description to manage your secrets.
Click Create. A New Global credential is created, as a Secret Text (Kind). A key sign on your new credential row indicates the secret Kind.
To add Client ID and Client Secret, click + Add Credentials again.
In the Kind field, select Username with password.
Set ID to
scribe-production-auth-id
(lowercase).Copy the Client ID provided by Scribe to the Username.
Copy the Client Secret provided by Scribe to the Password.
Leave Scope as Global.
Click Create.
Another Global credential is created as a Username with Password (Kind)
The final state of the secrets definition should be as shown in the following screenshot:
Avoiding costly commits
To avoid potentially costly commits, we recommended adding the Scribe output directory to your .gitignore file.
By default, add **/scribe
to your .gitignore.
Procedure
Scribe installation includes Command Line Interpreter (CLI) tools. Scribe provides the following a CLI tool called Valint. This tool is used to generate evidence in the form of SBOMs as well as SLSA provenance.
Every integration pipeline is unique. Integrating Scribe's code into your pipeline varies from one case to another.
The following are examples that illustrate where to add Scribe code snippets.
The code in these examples of a workflow executes these steps:
- Calls
valint
right after checkout to collect hash value evidence of the source code files and upload the evidence. - Calls
valint
to generate an SBOM from the final Docker image and upload the evidence.
The examples use a sample pipeline building a Mongo express project.
Jenkins over Docker
Prerequisites
Jenkins extensions installed:
A
docker
is installed on your build node in Jenkins.
Procedure
Sample integration code
pipeline {
agent any
environment {
SCRIBE_PRODUCT_KEY = credentials('scribe-product-key')
}
stages {
stage('checkout') {
steps {
cleanWs()
sh 'git clone -b v1.0.0-alpha.4 --single-branch https://github.com/mongo-express/mongo-express.git mongo-express-scm'
}
}
stage('sbom') {
agent {
docker {
image 'scribesecuriy.jfrog.io/scribe-docker-public-local/valint:latest'
reuseNode true
args "--entrypoint="
}
}
steps {
withCredentials([usernamePassword(credentialsId: 'scribe-staging-auth-id', usernameVariable: 'SCRIBE_CLIENT_ID', passwordVariable: 'SCRIBE_CLIENT_SECRET')]) {
sh '''
valint bom dir:mongo-express-scm \
--context-type jenkins \
--output-directory ./scribe/valint \
--product-key $SCRIBE_PRODUCT_KEY \
-E -U $SCRIBE_CLIENT_ID -P $SCRIBE_CLIENT_SECRET
'''
}
}
}
stage('image-bom') {
agent {
docker {
image 'scribesecuriy.jfrog.io/scribe-docker-public-local/valint:latest'
reuseNode true
args "--entrypoint="
}
}
steps {
withCredentials([usernamePassword(credentialsId: 'scribe-staging-auth-id', usernameVariable: 'SCRIBE_CLIENT_ID', passwordVariable: 'SCRIBE_CLIENT_SECRET')]) {
sh '''
valint bom mongo-express:1.0.0-alpha.4 \
--context-type jenkins \
--output-directory ./scribe/valint \
--product-key $SCRIBE_PRODUCT_KEY \
-E -U $SCRIBE_CLIENT_ID -P $SCRIBE_CLIENT_SECRET'''
}
}
}
}
}
See Also
Jenkins over Kubernetes (K8s)
Prerequisites
Jenkins over Kubernetes installed.
Procedure
Sample integration code
pipeline {
agent {
kubernetes {
yamlFile 'jenkins/k8s/scribe-test/KubernetesPod.yaml'
}
}
environment {
SCRIBE_PRODUCT_KEY = credentials('scribe-product-key')
}
stages {
stage('checkout-bom') {
steps {
container('git') {
sh 'git clone -b v1.0.0-alpha.4 --single-branch https://github.com/mongo-express/mongo-express.git mongo-express-scm'
}
container('valint') {
withCredentials([usernamePassword(credentialsId: 'scribe-staging-auth-id', usernameVariable: 'SCRIBE_CLIENT_ID', passwordVariable: 'SCRIBE_CLIENT_SECRET')]) {
sh '''
valint bom dir:mongo-express-scm \
--context-type jenkins \
--output-directory ./scribe/valint \
-E -U $SCRIBE_CLIENT_ID -P $SCRIBE_CLIENT_SECRET \
--product-key $SCRIBE_PRODUCT_KEY'''
}
}
}
}
stage('image-bom') {
steps {
container('valint') {
withCredentials([usernamePassword(credentialsId: 'scribe-staging-auth-id', usernameVariable: 'SCRIBE_CLIENT_ID', passwordVariable: 'SCRIBE_CLIENT_SECRET')]) {
sh '''
valint bom mongo-express:1.0.0-alpha.4 \
--context-type jenkins \
--output-directory ./scribe/valint \
-E -U $SCRIBE_CLIENT_ID -P $SCRIBE_CLIENT_SECRET \
--product-key $SCRIBE_PRODUCT_KEY'''
}
}
}
}
}
}
This example uses Jenkins over k8s plugin with the Pod template defined like this:
metadata:
labels:
some-label: jsl-scribe-test
spec:
containers:
- name: jnlp
env:
- name: CONTAINER_ENV_VAR
value: jnlp
- name: valint
image: scribesecuriy.jfrog.io/scribe-docker-public-local/valint:latest
command:
- cat
tty: true
- name: git
image: alpine/git
command:
- cat
tty: true
See Also
Jenkins Vanilla (No Agent)
Prerequisites
curl
installed on your build node in jenkins.
Procedure
Sample integration code
pipeline {
agent any
environment {
SCRIBE_PRODUCT_KEY = credentials('scribe-product-key')
PATH="./temp/bin:$PATH"
}
stages {
stage('install') {
steps {
cleanWs()
sh 'curl -sSfL https://raw.githubusercontent.com/scribe-security/misc/master/install.sh | sh -s -- -b ./temp/bin'
}
}
stage('checkout') {
steps {
sh 'git clone -b v1.0.0-alpha.4 --single-branch https://github.com/mongo-express/mongo-express.git mongo-express-scm'
}
}
stage('sbom') {
steps {
withCredentials([usernamePassword(credentialsId: 'scribe-staging-auth-id', usernameVariable: 'SCRIBE_CLIENT_ID', passwordVariable: 'SCRIBE_CLIENT_SECRET')]) {
sh '''
valint bom dir:mongo-express-scm \
--context-type jenkins \
--output-directory ./scribe/valint \
--product-key $SCRIBE_PRODUCT_KEY \
-E -U $SCRIBE_CLIENT_ID -P $SCRIBE_CLIENT_SECRET
'''
}
}
}
stage('image-bom') {
steps {
withCredentials([usernamePassword(credentialsId: 'scribe-staging-auth-id', usernameVariable: 'SCRIBE_CLIENT_ID', passwordVariable: 'SCRIBE_CLIENT_SECRET')]) {
sh '''
valint bom mongo-express:1.0.0-alpha.4 \
--context-type jenkins \
--output-directory ./scribe/valint \
--product-key testing \
-E -U $SCRIBE_CLIENT_ID -P $SCRIBE_CLIENT_SECRET'''
}
}
}
}
}