Skip to main content

Azure Pipelines

Use the following instructions to integrate your Azure pipelines with Scribe.

Installation

Valint-task Can be found in Azure marketplace.
Follow install-an-extension to add the extension to your organization.
Once you have the extension installed you can use the task in your pipeline.

1. Obtain a Scribe Hub API Token

  1. Sign in to Scribe Hub. If you don't have an account you can sign up for free here.

  2. Create a API token in Scribe Hub > Settings > Tokens. Copy it to a safe temporary notepad until you complete the integration.

Important

The token is a secret and will not be accessible from the UI after you finalize the token generation.

2. Add the API token to the Azure DevOps secrets

Add the Scribe Hub API token as SCRIBE_TOKEN to your Azure environment by following the instructions in Azure DevOps - Set secret variables.

3. Install Scribe CLI

Valint (Scribe CLI) is required to generate evidence in such as SBOMs and SLSA provenance.

  1. Install Azure DevOps Valint-task from the Azure marketplace.
  2. Follow install-an-extension to add the extension to your organization and use the task in your pipelines.

4. Instrument your build scripts

Basic example

Generate an SBOM of an image built in the pipeline by adding a step to call Valint at the end of the build. In your Azure DevOps project make sure you have a file named azure-pipelines.yml and add the following steps to it after the build step:

  - job: scribe_azure_job
displayName: scribe azure job

pool:
vmImage: 'ubuntu-latest'

steps:
- task: ScribeInstall@0
- task: ValintCli@0
displayName: SBOM image `busybox:latest`.
command: bom
target: nginx
format: statement
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)

Additional examples

Generate an SBOM for an image in a public registry
- task: ValintCli@0
displayName: Generate cyclonedx json SBOM
inputs:
commandName: bom
target: busybox:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint

scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Add NTIA metadata to SBOM
trigger:
branches:
include:
- main

jobs:
- job: scribe_azure_job
displayName: 'Scribe Azure Job'
pool:
name: {Update pool name here} # Example: Mikey
agent: {Update agent name here} # Example: azure-runner-ubuntu

variables:
imageName: 'pipelines-javascript-docker'
# SBOM Author meta data - Optional
AUTHOR_NAME: John-Smith
AUTHOR_EMAIL: john@thiscompany.com
AUTHOR_PHONE: 555-8426157
# SBOM Supplier meta data - Optional
SUPPLIER_NAME: Scribe-Security
SUPPLIER_URL: www.scribesecurity.com
SUPPLIER_EMAIL: info@scribesecurity.com
SUPPLIER_PHONE: 001-001-0011

steps:
- task: scribeInstall@0

- task: ValintCli@0
inputs:
command: bom
target: nginx
format: statement
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
author-name: $(AUTHOR_NAME)
author-email: $(AUTHOR_EMAIL)
author-phone: $(AUTHOR_PHONE)
supplier-name: $(SUPPLIER_NAME)
supplier-url: $(SUPPLIER_URL)
supplier-email: $(SUPPLIER_EMAIL)
supplier-phone: $(SUPPLIER_PHONE)

- task: ValintCli@0
inputs:
command: verify
target: nginx
inputFormat: statement
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate SLSA provenance for an image in a public registry
- task: ValintCli@0
displayName: Generate SLSA provenance
inputs:
commandName: slsa
target: busybox:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate an SBOM for for an image built with local docker
- task: ValintCli@0
displayName: Generate cyclonedx json SBOM
inputs:
commandName: bom
target: image_name:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate SLSA provenance for for an image built with local docker
- task: ValintCli@0
displayName: Generate SLSA provenance
inputs:
commandName: slsa
target: image_name:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate an SBOM for an image in a private registry

Add a docker login task before the adding the following task:

- task: ValintCli@0
displayName: Generate cyclonedx json SBOM
inputs:
commandName: bom
target: scribesecurity.jfrog.io/scribe-docker-local/example:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate SLSA provenance for an image in a private registry

Before the following task add a docker login task

- task: ValintCli@0
displayName: Generate SLSA provenance
inputs:
commandName: slsa
target: scribesecurity.jfrog.io/scribe-docker-local/example:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Add custom metadata to SBOM
- job: custom_bom
displayName: Custom bom

variables:
- name: test_env
value: test_env_value

pool:
vmImage: 'ubuntu-latest'

steps:
- task: ValintCli@0
displayName: Generate cyclonedx json SBOM - add metadata - labels, envs, name
inputs:
commandName: bom
target: 'busybox:latest'
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
env: test_env
label: test_label
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Add custom metadata to SLSA provenance
- job: custom_slsa
displayName: Custom slsa

variables:
- name: test_env
value: test_env_value

pool:
vmImage: 'ubuntu-latest'

steps:
- task: ValintCli@0
displayName: Generate cyclonedx json SBOM - add metadata - labels, envs, name
inputs:
commandName: slsa
target: 'busybox:latest'
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
env: test_env
label: test_label
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Export SBOM as an artifact

Use format input argumnet to set the format.

- task: ValintCli@0
displayName: SBOM image `busybox:latest`.
inputs:
command: bom
target: busybox:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
outputFile: $(Build.ArtifactStagingDirectory)/my_sbom.json
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)

# Using `outputDirectory` evidence cache dir
- publish: $(Build.ArtifactStagingDirectory)/scribe/valint
artifact: scribe-evidence

# Using `outputFile` custom path.
- publish: $(Build.ArtifactStagingDirectory)/my_sbom.json
artifact: scribe-sbom
Export SLSA provenance as an artifact

Use format input argumnet to set the format.

- task: ValintCli@0
displayName: SLSA image `busybox:latest`.
inputs:
command: slsa
target: busybox:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
outputFile: $(Build.ArtifactStagingDirectory)/my_slsa.json
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)

# Using `outputDirectory` evidence cache dir
- publish: $(Build.ArtifactStagingDirectory)/scribe/valint
artifact: scribe-evidence

# Using `outputFile` custom path.
- publish: $(Build.ArtifactStagingDirectory)/my_slsa.json
artifact: scribe-slsa
Generate an SBOM of a local file directory
- bash: |
mkdir testdir
echo "test" > testdir/test.txt

- task: ValintCli@0
displayName: SBOM local directory.
inputs:
command: bom
target: dir:testdir
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate SLSA provenance of a local file directory
- bash: |
mkdir testdir
echo "test" > testdir/test.txt

- task: ValintCli@0
displayName: SLSA local directory.
inputs:
command: slsa
target: dir:testdir
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)

Generate an SBOM of a git repo
For a remote git repo: ```YAML - task: ValintCli@0 displayName: SBOM remote git repository. inputs: command: bom target: git:https://github.com/mongo-express/mongo-express.git outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint scribeEnable: true scribeClientSecret: $(SCRIBE_TOKEN) ``` For a local git repo: **Note** If you use implicit checkout, **[git-strategy](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/steps-checkout?view=azure-pipelines)** affects the commits collected into the SBOM.
- checkout: self

- task: ValintCli@0
displayName: SBOM local git repository.
inputs:
command: bom
target: git:.
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
scribeEnable: true
scribeClientSecret: $(SCRIBE_TOKEN)
Generate SLSA provenance of a git reop
For a remote git repo: ```YAML - task: ValintCli@0 displayName: SBOM remote git repository. inputs: command: slsa target: git:https://github.com/mongo-express/mongo-express.git outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint ```

For a local git repo

- checkout: self

- task: ValintCli@0
displayName: SLSA local git repository.
inputs:
command: slsa
target: git:.
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint

Using an OCI registry as an evidence store instead of Scribe Hub
For on-prem deployment scenarios where you do not want to utilize Scribe Hub as a SaaS you can store, retrieve, and verify evidence with an OCI Resitry (learn more)

Related flags:

  • --oci Enable OCI store.
  • --oci-repo - Evidence store location.
  1. Allow Valint Read and Write access to this registry.
  2. Login to the registry, for example by docker login.
- job: scribe_azure_job
pool:
vmImage: 'ubuntu-latest'

variables:
imageName: 'pipelines-javascript-docker'

steps:
- script: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin [my_registry]

- task: scribeInstall@0

- task: ValintCli@0
inputs:
commandName: bom
target: [target]
format: [attest, statement]
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
oci: true
ociRepo: [oci_repo]

- task: ValintCli@0
inputs:
commandName: verify
target: [target]
inputFormat: [attest, statement, attest-slsa, statement-slsa, attest-generic, statement-generic]
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
oci: true
ociRepo: [oci_repo]

Basic examples

Public registry image (SBOM)

Create SBOM for remote busybox:latest image.

- task: ValintCli@0
displayName: Generate cyclonedx json SBOM
inputs:
commandName: bom
target: busybox:latest
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
force: true

Alternative evidence stores

You can learn more about alternative stores here.

OCI Evidence store

Valint supports both storage and verification flows for attestations and statement objects utilizing OCI registry as an evidence store.

Using OCI registry as an evidence store allows you to upload, download and verify evidence across your supply chain in a seamless manner.

Related flags:

  • oci Enable OCI store.
  • ociRepo - Evidence store location.

Before you begin

Evidence can be stored in any accusable registry.

  • Write access is required for upload (generate).
  • Read access is required for download (verify).

You must first login with the required access privileges to your registry before calling Valint. For example, using docker login command.

Usage

- job: scribe_azure_job
pool:
vmImage: 'ubuntu-latest'

variables:
imageName: 'pipelines-javascript-docker'

steps:
- script: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin [my_registry]

- task: scribeInstall@0

- task: ValintCli@0
inputs:
commandName: bom
target: [target]
format: [attest, statement]
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
oci: true
ociRepo: [oci_repo]

- task: ValintCli@0
inputs:
commandName: verify
target: [target]
inputFormat: [attest, statement, attest-slsa, statement-slsa, attest-generic, statement-generic]
outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
oci: true
ociRepo: [oci_repo]