Skip to main content

Snyk

Our Snyk integration allows you to import targets, projects and issues from your Snyk account into Port, according to your mapping and definitions.

Common use casesโ€‹

  • Map targets, projects and issues in your Snyk organization environment.
  • Watch for object changes (create/update/delete) in real-time, and automatically apply the changes to your entities in Port.
  • Create/delete Snyk objects using self-service actions.

Prerequisitesโ€‹

To install the integration, you need a Kubernetes cluster that the integration's container chart will be deployed to.

Please make sure that you have kubectl and helm installed on your machine, and that your kubectl CLI is connected to the Kubernetes cluster where you plan to install the integration.

installationโ€‹

Choose one of the following installation methods:

Using this installation option means that the integration will be able to update Port in real time using webhooks.

This table summarizes the available parameters for the installation. Set them as you wish in the script below, then copy it and run it in your terminal:

ParameterDescriptionRequired
port.clientIdYour port client idโœ…
port.clientSecretYour port client secretโœ…
port.baseUrlYour port base url, relevant only if not using the default port appโŒ
integration.identifierChange the identifier to describe your integrationโœ…
integration.typeThe integration typeโœ…
integration.eventListener.typeThe event listener typeโœ…
integration.secrets.tokenThe Snyk API tokenโœ…
integration.config.organizationIdThe Snyk organization IDโœ…
integration.config.apiUrlThe Snyk API URL. If not specified, the default will be https://api.snyk.ioโŒ
integration.config.appHostThe host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in SnykโŒ
integration.secret.webhookSecretThis is a password you create, that Snyk uses to sign webhook events to PortโŒ
scheduledResyncIntervalThe number of minutes between each resyncโŒ
initializePortResourcesDefault true, When set to true the integration will create default blueprints and the port App config MappingโŒ

helm repo add --force-update port-labs https://port-labs.github.io/helm-charts
helm upgrade --install my-snyk-integration port-labs/port-ocean \
--set port.clientId="PORT_CLIENT_ID" \
--set port.clientSecret="PORT_CLIENT_SECRET" \
--set port.baseUrl="https://api.getport.io" \
--set initializePortResources=true \
--set scheduledResyncInterval=120 \
--set integration.identifier="my-snyk-integration" \
--set integration.type="snyk" \
--set integration.eventListener.type="POLLING" \
--set integration.secrets.token="SNYK_TOKEN" \
--set integration.config.organizationId="ORG_ID"

Ingesting Snyk objectsโ€‹

The Snyk integration uses a YAML configuration to describe the process of loading data into the developer portal.

Here is an example snippet from the config which demonstrates the process for getting project data from Snyk:

createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: project
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .attributes.name
blueprint: '"snykProject"'
properties:
url: ("https://app.snyk.io/org/" + .relationships.organization.data.id + "/project/" + .id | tostring)
owner: .__owner.email
businessCriticality: .attributes.business_criticality
environment: .attributes.environment
lifeCycle: .attributes.lifecycle
highOpenVulnerabilities: .meta.latest_issue_counts.high
mediumOpenVulnerabilities: .meta.latest_issue_counts.medium
lowOpenVulnerabilities: .meta.latest_issue_counts.low
criticalOpenVulnerabilities: .meta.latest_issue_counts.critical
importedBy: .__importer.email
tags: .attributes.tags

The integration makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from Snyk's API events.

Configuration structureโ€‹

The integration configuration determines which resources will be queried from Snyk, and which entities and properties will be created in Port.

Supported resources

The following resources can be used to map data from Snyk, it is possible to reference any field that appears in the API responses linked below for the mapping configuration.

  • The root key of the integration configuration is the resources key:

    resources:
    - kind: project
    selector:
    ...
  • The kind key is a specifier for a Snyk object:

      resources:
    - kind: project
    selector:
    ...
  • The selector and the query keys allow you to filter which objects of the specified kind will be ingested into your software catalog:

    resources:
    - kind: project
    selector:
    query: "true" # JQ boolean expression. If evaluated to false - this object will be skipped.
    port:
  • The port, entity and the mappings keys are used to map the Snyk object fields to Port entities. To create multiple mappings of the same kind, you can add another item in the resources array;

    resources:
    - kind: project
    selector:
    query: "true"
    port:
    entity:
    mappings: # Mappings between one Snyk object to a Port entity. Each value is a JQ query.
    identifier: .id
    title: .attributes.name
    blueprint: '"snykProject"'
    properties:
    url: ("https://app.snyk.io/org/" + .relationships.organization.data.id + "/project/" + .id | tostring)
    owner: .__owner.email
    businessCriticality: .attributes.business_criticality
    environment: .attributes.environment
    lifeCycle: .attributes.lifecycle
    highOpenVulnerabilities: .meta.latest_issue_counts.high
    mediumOpenVulnerabilities: .meta.latest_issue_counts.medium
    lowOpenVulnerabilities: .meta.latest_issue_counts.low
    criticalOpenVulnerabilities: .meta.latest_issue_counts.critical
    importedBy: .__importer.email
    tags: .attributes.tags
    - kind: project # In this instance project is mapped again with a different filter
    selector:
    query: '.name == "MyProjectName"'
    port:
    entity:
    mappings: ...

    :::tip Blueprint key Note the value of the blueprint key - if you want to use a hardcoded string, you need to encapsulate it in 2 sets of quotes, for example use a pair of single-quotes (') and then another pair of double-quotes (") :::

Ingest data into Portโ€‹

To ingest Snyk objects using the integration configuration, you can follow the steps below:

  1. Go to the DevPortal Builder page.
  2. Select a blueprint you want to ingest using Snyk.
  3. Choose the Ingest Data option from the menu.
  4. Select Snyk under the Code quality & security providers category.
  5. Modify the configuration according to your needs.
  6. Click Resync.

Examplesโ€‹

Examples of blueprints and the relevant integration configurations:

Targetโ€‹

Target blueprint
{
"identifier": "snykTarget",
"title": "Snyk Target",
"icon": "Snyk",
"schema": {
"properties": {
"criticalOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open Critical Vulnerabilities"
},
"highOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open High Vulnerabilities"
},
"mediumOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open Medium Vulnerabilities"
},
"lowOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open Low Vulnerabilities"
},
"origin": {
"title": "Target Origin",
"type": "string",
"enum": [
"artifactory-cr",
"aws-config",
"aws-lambda",
"azure-functions",
"azure-repos",
"bitbucket-cloud",
"bitbucket-server",
"cli",
"cloud-foundry",
"digitalocean-cr",
"docker-hub",
"ecr",
"gcr",
"github",
"github-cr",
"github-enterprise",
"gitlab",
"gitlab-cr",
"google-artifact-cr",
"harbor-cr",
"heroku",
"ibm-cloud",
"kubernetes",
"nexus-cr",
"pivotal",
"quay-cr",
"terraform-cloud"
]
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
- kind: target
selector:
query: "true"
port:
entity:
mappings:
identifier: .attributes.displayName
title: .attributes.displayName
blueprint: '"snykTarget"'
properties:
origin: .attributes.origin
highOpenVulnerabilities: "[.__projects[].meta.latest_issue_counts.high] | add"
mediumOpenVulnerabilities: "[.__projects[].meta.latest_issue_counts.medium] | add"
lowOpenVulnerabilities: "[.__projects[].meta.latest_issue_counts.low] | add"
criticalOpenVulnerabilities: "[.__projects[].meta.latest_issue_counts.critical] | add"

Projectโ€‹

Project blueprint
{
"identifier": "snykProject",
"description": "This blueprint represents a snyk project in our software catalog",
"title": "Snyk Project",
"icon": "Snyk",
"schema": {
"properties": {
"url": {
"type": "string",
"title": "URL",
"format": "url",
"icon": "Snyk"
},
"owner": {
"type": "string",
"title": "Owner",
"format": "user",
"icon": "TwoUsers"
},
"businessCriticality": {
"title": "Business Criticality",
"type": "array",
"items": {
"type": "string",
"enum": ["critical", "high", "medium", "low"]
},
"icon": "DefaultProperty"
},
"environment": {
"items": {
"type": "string",
"enum": [
"frontend",
"backend",
"internal",
"external",
"mobile",
"saas",
"onprem",
"hosted",
"distributed"
]
},
"icon": "Environment",
"title": "Environment",
"type": "array"
},
"lifeCycle": {
"title": "Life Cycle",
"type": "array",
"items": {
"type": "string",
"enum": ["development", "sandbox", "production"]
},
"icon": "DefaultProperty"
},
"highOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open High Vulnerabilities"
},
"mediumOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open Medium Vulnerabilities"
},
"lowOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open Low Vulnerabilities"
},
"criticalOpenVulnerabilities": {
"icon": "Vulnerability",
"type": "number",
"title": "Open Low Vulnerabilities"
},
"importedBy": {
"icon": "TwoUsers",
"type": "string",
"title": "Imported By",
"format": "user"
},
"tags": {
"type": "array",
"title": "Tags",
"icon": "DefaultProperty"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
resources:
- kind: project
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .attributes.name
blueprint: '"snykProject"'
properties:
url: ("https://app.snyk.io/org/" + .relationships.organization.data.id + "/project/" + .id | tostring)
owner: .__owner.email
businessCriticality: .attributes.business_criticality
environment: .attributes.environment
lifeCycle: .attributes.lifecycle
highOpenVulnerabilities: .meta.latest_issue_counts.high
mediumOpenVulnerabilities: .meta.latest_issue_counts.medium
lowOpenVulnerabilities: .meta.latest_issue_counts.low
criticalOpenVulnerabilities: .meta.latest_issue_counts.critical
importedBy: .__importer.email
tags: .attributes.tags

Issueโ€‹

Issue blueprint
{
"identifier": "snykVulnerability",
"description": "This blueprint represents a Snyk vulnerability in our software catalog",
"title": "Snyk Vulnerability",
"icon": "Snyk",
"schema":
{
"properties":
{
"score": { "icon": "Star", "type": "number", "title": "Score" },
"packageName":
{
"type": "string",
"title": "Package Name",
"icon": "DefaultProperty",
},
"packageVersions":
{ "icon": "Package", "title": "Package Versions", "type": "array" },
"type":
{
"type": "string",
"title": "Type",
"enum": ["vuln", "license", "configuration"],
"icon": "DefaultProperty",
},
"severity":
{
"icon": "Alert",
"title": "Issue Severity",
"type": "string",
"enum": ["low", "medium", "high", "critical"],
"enumColors":
{
"low": "green",
"medium": "yellow",
"high": "red",
"critical": "red",
},
},
"url":
{
"icon": "Link",
"type": "string",
"title": "Issue URL",
"format": "url",
},
"language":
{
"type": "string",
"title": "Language",
"icon": "DefaultProperty",
},
"publicationTime":
{
"type": "string",
"format": "date-time",
"title": "Publication Time",
"icon": "DefaultProperty",
},
"isPatched":
{
"type": "boolean",
"title": "Is Patched",
"icon": "DefaultProperty",
},
},
"required": [],
},
"mirrorProperties": {},
"calculationProperties": {},
"relations":
{
"snykProject":
{
"title": "Project",
"target": "snykProject",
"required": false,
"many": false,
},
},
}
Integration configuration
resources:
- kind: vulnerability
selector:
query: '.issueType == "vuln"'
port:
entity:
mappings:
identifier: .issueData.id
title: .issueData.title
blueprint: '"snykVulnerability"'
properties:
score: .priorityScore
packageName: .pkgName
packageVersions: .pkgVersions
type: .issueType
severity: .issueData.severity
url: .issueData.url
language: .issueData.language // .issueType
publicationTime: .issueData.publicationTime
isPatched: .isPatched
relations:
snykProject: .__project.id