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
Create an API token in Scribe Hub > Account > Tokens. Copy it to a safe temporary notepad until you complete the integration.
:::note 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.
- Install Azure DevOps Valint-task from the Azure marketplace.
 
- 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@2
    - task: ValintCli@2
      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@2
  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@2
  - task: ValintCli@2
    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@2
    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@2
  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@2
  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 an image built with local docker 
- task: ValintCli@2
  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 adding the following task:
- task: ValintCli@2
  displayName: Generate cyclonedx json SBOM
  inputs:
    commandName: bom
    target: scribesecurity/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@2
  displayName: Generate SLSA provenance
  inputs:
    commandName: slsa
    target: scribesecurity/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@2
    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@2
    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@2
  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@2
  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@2
  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@2
  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@2
  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@2
  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@2
  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@2
  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. 
- Allow Valint Read and Write access to this registry.
 
- 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@2
  - task: ValintCli@2
    inputs:
      commandName: bom
      target: [target]
      format: [attest, statement]
      outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
      oci: true
      ociRepo: [oci_repo]
  - task: ValintCli@2
    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@2
  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 the OCI registry as an evidence store.
Using the 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@2
  - task: ValintCli@2
    inputs:
      commandName: bom
      target: [target]
      format: [attest, statement]
      outputDirectory: $(Build.ArtifactStagingDirectory)/scribe/valint
      oci: true
      ociRepo: [oci_repo]
  - task: ValintCli@2
    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]