Skip to main content

Run Snyk scans and ingest results

This workflow describes how to ingest Snyk scan results into a Harness pipeline. STO supports the following scan approaches for the following Snyk products:

Important notes for running Snyk scans in STO

Snyk repository orchestration example

This example uses a Snyk step in Orchestration mode to scan a repository. This is the simplest workflow: the Snyk step runs the scan and ingests the results, with minimal configuration required.

  1. Add a codebase connector that points to the repository you want to scan.

  2. Add a Security Tests or Build stage to your pipeline.

  1. Add a Snyk security step to ingest the results of the scan. In this example, the step is configured as follows:

    1. Scan Mode = Orchestration
    2. Target Type = Repository
    3. Target Name = (user-defined)
    4. Variant = (user-defined)
    5. Access Token = <+secrets.getValue("snyk_api_token")> (Harness secret)
  2. Apply your changes, then save and run the pipeline.

Snyk repository ingestion example

The following example uses snyk test to scan a .NET repository.

The scan stage in this pipeline has the following steps:

  • A Run step installs the build; then it scans the image and saves the output to a shared folder.

  • A Snyk step then ingests the output file.

  1. Add a codebase connector to your pipeline that points to the repository you want to scan.

  2. Add a Security Tests or Build stage to your pipeline.

  3. Go to the Overview tab of the stage. Under Shared Paths, enter the following path: /shared/customer_artifacts.

  4. Add a Run step that runs the build (if required), scans the repo, and saves the results to the shared folder:

    1. In the Run step Command field, add code to build a local image (if required) and save the scan results to the shared folder.

      In this example, we want to scan a .NET repository. The setup requirements topic says: Build only required if no packages.config file present. The repo does not contain this file. Enter the following code in the Command field:

      # populates the dotnet dependencies
      dotnet restore SubSolution.sln

      # scan the code repository
      snyk code test \
      --file=SubSolution.sln \
      --sarif-file-output=/shared/customer_artifacts/snyk_scan_results.sarif || true
    2. For the Run step Image, use a supported Snyk image based on the type of code in your codebase.

    3. In the Run step Environment Variables field, under Optional Configuration, add a variable to access your Snyk API key:

      SNYK_TOKEN = <+secrets.getValue("snyk_api_token")>`

      Your Run step should now look like this:

    4. In the Run step > Advanced tab > Failure Strategies, set the Failure Strategy to Mark as Success.

      This step is required to ensure that the pipeline proceeds if Snyk finds a vulnerability. Otherwise, the build will exit with an error code before STO can ingest the data.

  5. Add a Snyk security step to ingest the results of the scan. In this example, the step is configured as follows:

    1. Scan Mode = Ingestion
    2. Target Type = Repository
    3. Target Name = (user-defined)
    4. Variant = (user-defined)
    5. Ingestion = /shared/customer_artifacts/snyk_scan_results.sarif
  6. Apply your changes, then save and run the pipeline.

Snyk container image ingestion example

This example uses snyk container test to scan a container image. The scan stage consists of three steps:

  • A Background step that runs Docker-in-Docker as a background service in Privileged mode (required when scanning a container image).

  • A Run step that scans the image and publishes the results to a SARIF file.

  • A Snyk step that ingests the scan results.

  1. Add a Security Tests or Build stage to your pipeline.

  2. Add a Background step to the stage and set it up as follows:

    1. Dependency Name = dind
    2. Container Registry = The Docker connector to download the DinD image. If you don't have one defined, go to Docker connector settings reference.
    3. Image = docker:dind
    4. Under Optional Configuration, select the Privileged option.
  3. Add a Run step and set it up as follows:

    1. Container Registry = Select a Docker Hub connector.

    2. Image = snyk/snyk:docker

    3. Shell = Sh

    4. Command — Enter code to run the scan and save the results to SARIF:

      snyk container test \
      snykgoof/big-goof-1g:100 -d \
      --sarif-file-output=/shared/customer_artifacts/snyk_container_scan.sarif || true

      Snyk maintains a set of snykgoof repositories that you can use for testing your container-image scanning workflows.

    5. Under Optional Configuration, select the Privileged option.

    6. Under Environment Variables, add a variable for your Snyk API token. Make sure that you save your token to a Harness secret:

      SNYK_TOKEN = <+secrets.getValue("snyk_api_token")>

    7. In the Run step > Advanced tab > Failure Strategies, set the Failure Strategy to Mark as Success.

      This step is required to ensure that the pipeline proceeds if Snyk finds a vulnerability. Otherwise, the build will exit with an error code before STO can ingest the data.

  4. Add a Snyk step and configure it as follows:

    1. Scan Mode = Ingestion
    2. Target Type = Container Image
    3. Target Name = (user-defined)
    4. Variant = (user-defined)
    5. Ingestion = /shared/customer_artifacts/snyk_container_scan.sarif
  5. Apply your changes, then save and run the pipeline.

Snyk Infrastructure as Code (IaC) repository ingestion example

note

Support for Snyk scans of IaC repositories is a beta feature. For more information, contact Harness Support.

The following example uses snyk iac test to scan a an IaC code repository.

The scan stage in this pipeline has the following steps:

  • A Run step installs the build; then it scans the image and saves the output to a shared folder.

  • A Snyk step then ingests the output file.

  1. Add a codebase connector to your pipeline that points to the repository you want to scan.

  2. Add a Security Tests or Build stage to your pipeline.

  3. Go to the Overview tab of the stage. Under Shared Paths, enter the following path: /shared/customer_artifacts

  4. Add a Run step that runs the build (if required), scans the repo, and saves the results to the shared folder:

    1. In the Run step Command field, add code to run the scan and save the scan results to the shared folder.

      snyk iac test --sarif --sarif-file-output=/shared/customer_artifacts/snyk_iac.json /harness || true
      cat /shared/customer_artifacts/snyk_iac.json
    2. For the Run step Image, use a supported Snyk image based on the type of code in your codebase.

    3. In the Run step Environment Variables field, under Optional Configuration, add a variable to access your Snyk API key:

      SNYK_TOKEN = <+secrets.getValue("snyk_api_token")>`

      Your Run step should now look like this:

    4. In the Run step > Advanced tab > Failure Strategies, set the Failure Strategy to Mark as Success.

      This step is required to ensure that the pipeline proceeds if Snyk finds a vulnerability. Otherwise, the build will exit with an error code before STO can ingest the data.

  5. Add a Snyk security step to ingest the results of the scan. In this example, the step is configured as follows:

    1. Scan Mode = Ingestion
    2. Target Type = Repository
    3. Target Name = (user-defined)
    4. Variant = (user-defined)
    5. Ingestion = /shared/customer_artifacts/snyk_iac.sarif
  6. Apply your changes, then save and run the pipeline.

Snyk pipeline examples

Snyk code repository scan (orchestration)

The following illustrates the repository orchestration workflow example above for scanning a Java project.

YAML pipeline, repository scan, Orchestration mode

pipeline:
projectIdentifier: STO
orgIdentifier: default
tags: {}
properties:
ci:
codebase:
connectorRef: CODEBASE_CONNECTOR_snyklabs
repoName: java-goof
build: <+input>
stages:
- stage:
name: scan
identifier: scan
description: ""
type: SecurityTests
spec:
cloneCodebase: true
infrastructure:
type: KubernetesDirect
spec:
connectorRef: K8S_DELEGATE_CONNECTOR
namespace: harness-delegate-ng
automountServiceAccountToken: true
nodeSelector: {}
os: Linux
execution:
steps:
- step:
type: Snyk
name: snyk java scan
identifier: snyk_java_scan
spec:
mode: orchestration
config: default
target:
name: snyk-labs-java-goof
type: repository
variant: main
advanced:
log:
level: debug
args:
cli: "-d -X"
imagePullPolicy: Always
auth:
access_token: <+secrets.getValue("snyk_api_token")>
identifier: snyk_orchestration_doc_example
name: snyk_orchestration_doc_example


Snyk code repository scan (ingestion)

The following illustrates the repository ingestion workflow example above for building and scanning a .NET image.

YAML pipeline, repository scan, Ingestion mode

pipeline:
projectIdentifier: STO
orgIdentifier: default
tags: {}
properties:
ci:
codebase:
connectorRef: CODEBASE_CONNECTOR_Subsolution
repoName: SubSolution
build: <+input>
stages:
- stage:
name: test
identifier: test
type: SecurityTests
spec:
cloneCodebase: true
platform:
os: Linux
arch: Amd64
runtime:
type: Cloud
spec: {}
execution:
steps:
- step:
type: Run
name: Snyk_Build
identifier: Snyk_Build
spec:
connectorRef: CONTAINER_IMAGE_REGISTRY_CONNECTOR
image: snyk/snyk:dotnet
shell: Sh
command: |

# populates the dotnet dependencies
dotnet restore SubSolution.sln

# Test for any known security issues using Static Code Analysis
# https://docs.snyk.io/snyk-cli/commands/code-test
snyk code test \
--file=SubSolution.sln \
--sarif-file-output=/shared/customer_artifacts/snyk_scan_results.sarif || true

# Check project for open source vulnerabilities
# https://docs.snyk.io/snyk-cli/commands/test
# snyk test \
# --file=SubSolution.sln \
# --sarif-file-output=/shared/customer_artifacts/snyk_scan_results.sarif || true

envVariables:
SNYK_TOKEN: <+secrets.getValue("sto-api-token")>
- step:
type: Snyk
name: Snyk SAST
identifier: Snyk_SAST
spec:
mode: ingestion
config: default
target:
name: snyk-scan-example-for-docs
type: repository
variant: master
advanced:
log:
level: info
ingestion:
file: /shared/customer_artifacts/snyk_scan_results.sarif
sharedPaths:
- /shared/customer_artifacts
variables:
identifier: snyk_ingestion_doc_example
name: snyk_ingestion_doc_example

Snyk container image scan (ingestion)

The following illustrates the container image ingestion workflow example above for building and scanning a .NET image.

YAML pipeline, container image scan, Ingestion mode

pipeline:
allowStageExecutions: false
projectIdentifier: STO
orgIdentifier: default
tags: {}
stages:
- stage:
name: scan
identifier: build
type: CI
spec:
cloneCodebase: false
infrastructure:
type: KubernetesDirect
spec:
connectorRef: K8S_DELEGATE_CONNECTOR
namespace: harness-delegate-ng
automountServiceAccountToken: true
nodeSelector: {}
os: Linux
sharedPaths:
- /shared/customer_artifacts/
- /var/run
execution:
steps:
- step:
type: Background
name: background-dind-service
identifier: Background_1
spec:
connectorRef: CONTAINER_IMAGE_REGISTRY_CONNECTOR
image: docker:dind
shell: Sh
entrypoint:
- dockerd
privileged: true
- step:
type: Run
name: run-snyk-scan
identifier: Run_1
spec:
connectorRef: CONTAINER_IMAGE_REGISTRY_CONNECTOR
image: snyk/snyk:docker
shell: Sh
command: |
# https://docs.snyk.io/snyk-cli/commands/container-test
# https://docs.snyk.io/scan-applications/snyk-container/snyk-cli-for-container-security/advanced-snyk-container-cli-usage

snyk container test \
snykgoof/big-goof-1g:100 -d \
--sarif-file-output=/shared/customer_artifacts/snyk_container_scan.sarif || true
privileged: true
envVariables:
SNYK_TOKEN: <+secrets.getValue("snyk_api_token")>
isAnyParentContainerStepGroup: false
- step:
type: Snyk
name: snyk-ingest-step
identifier: Snyk_1
spec:
mode: ingestion
config: default
target:
name: snyk-goof-big-goof
type: container
variant: "100"
advanced:
log:
level: info
settings:
runner_tag: develop
imagePullPolicy: Always
ingestion:
file: /shared/customer_artifacts/snyk_container_scan.sarif
failureStrategies:
- onFailure:
errors:
- AllErrors
action:
type: Ignore
when:
stageStatus: Success
caching:
enabled: false
paths: []
variables:
- name: runner_tag
type: String
value: dev
identifier: snyk_ingest_image_docexample
name: "snyk - ingest - image - docexample "


Snyk IaC repository scan (ingestion)

The following illustrates the container image ingestion workflow example for building and scanning an IaC repository.

YAML pipeline, IaC repository scan, Ingestion mode

pipeline:
allowStageExecutions: false
projectIdentifier: STO
orgIdentifier: default
tags: {}
properties:
ci:
codebase:
connectorRef: CODEBASE_CONNECTOR_snyk_terraform_goof
build: <+input>
stages:
- stage:
name: scan
identifier: build
type: CI
spec:
cloneCodebase: true
infrastructure:
type: KubernetesDirect
spec:
connectorRef: K8S_DELEGATE_CONNECTOR
namespace: harness-delegate-ng
automountServiceAccountToken: true
nodeSelector: {}
os: Linux
sharedPaths:
- /shared/customer_artifacts/
execution:
steps:
- stepGroup:
name: Generation
identifier: Generation
steps:
- step:
type: Run
name: Snyk IaC Run
identifier: Run_1
spec:
connectorRef: CONTAINER_IMAGE_REGISTRY_CONNECTOR
image: snyk/snyk:linux
shell: Sh
command: |

# https://docs.snyk.io/snyk-cli/commands/iac-test
snyk iac test --sarif --sarif-file-output=/shared/customer_artifacts/snyk_iac.json /harness || true
cat /shared/customer_artifacts/snyk_iac.json

envVariables:
SNYK_TOKEN: <+secrets.getValue("snyk_api_token")>
isAnyParentContainerStepGroup: false
failureStrategies:
- onFailure:
errors:
- AllErrors
action:
type: Abort
- step:
type: Snyk
name: Snyk ingest
identifier: Snyk_1
spec:
mode: ingestion
config: default
target:
name: snyk/terraform-goof
type: repository
variant: master
advanced:
log:
level: info
settings:
runner_tag: develop
imagePullPolicy: Always
ingestion:
file: /shared/customer_artifacts/snyk_iac.json
failureStrategies:
- onFailure:
errors:
- AllErrors
action:
type: Ignore
when:
stageStatus: Success
variables:
- name: runner_tag
type: String
value: dev
failureStrategies:
- onFailure:
errors:
- AllErrors
action:
type: Abort
identifier: IaCv2_Snyk_docexample_Clone
name: IaCv2 - Snyk - docexample - Clone