This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Endor Labs integrations

Learn how to integrate Endor Labs with third-party services. Endor Labs provides several out-of-the-box integrations for continuous monitoring, ticketing, and messaging workflows in your environment.

1 - Set up custom package repositories

Learn how to configure custom package repositories for dependency resolution.

Suppose your software components are private and are hosted in an internal package repository. In that case, you must provide authentication credentials to the registry, to create a complete bill of materials or perform static analysis.

You must set up custom package repositories if:

  • Your software package isn’t scanned as part of a post-build or install step
  • You are using the Endor Labs GitHub App
  • you are implementing scans across your environment for quick visibility
  • Authentication information to your private package repository is hosted outside of the repository

If your software components are private and hosted in AWS CodeArtifact, set up an OpenID Connect provider in AWS and create roles with trust policies to allow Endor Labs access to your CodeArtifact repositories. See Configure package manager integrations with AWS.

Configure package manager integrations

Endor Labs integrates with your self-hosted package repositories and source control systems to give you visibility into your environment. Package manager integrations allow users to simplify scanning using custom repositories.

Endor Labs generally respects package authentication and configuration settings and a package manager integration is usually not required to scan private packages successfully.

  • Use package manager integrations to simplify scanning when authentication to private repositories is not part of standard manifest or settings files.

  • Package manager integrations allow you to set custom registries for each package ecosystem and the priority of each registry for scanning.

To set up a package manager integration:

  1. Under Manage, select Integrations.
  2. Select the package manager configuration you’d like to customize and click Connect
  3. In the upper right-hand corner, select Add Package Manager.
  4. Input a package manager URL for your given package registry.
  5. If a package registry is authenticated select Authenticate to this registry and enter a set of credentials that will be used to authenticate to the package registry.
  6. Select Add Package Manager.

If you would like to delete a package manager integration, click the trash can icon at the far right of the integration.

Change package manager integration priority

Package manager integrations allow you to set the priority of each package registry used by a package managers in your tenant namespace. This defines the location from which a package manager looks when it attempts to resolve dependencies for a software package.

To change the package manager integration priority:

  1. Click and hold the integration you would like to change the priority of.
  2. Drag the integration to the priority spot that is most frequently used by your organization.

Package manager integrations

The following support matrix details support for package manager integrations:

Language Ecosystem Supported
Java Maven (mvn://) Supported
JavaScript npm (npm://) Supported
Python PyPI (pypi://) Supported
Ruby Gem (gem://) Supported
PHP Composer (composer://) Supported
.NET/C# nuget (nuget://) Supported

1.1 - Configure integration with AWS

Learn how to configure package manager integrations with AWS CodeArtifact.

Configure Endor Labs to integrate with AWS CodeArtifact to use private libraries to build and scan your software.

You must Create an OpenID Connect provider in AWS IAM to allow Endor Labs to authenticate and assume roles securely. Then, configure an IAM role with a trust policy to grant Endor Labs read-only access to AWS CodeArtifact repositories.

You can configure the resources using the AWS Management Console, AWS CloudFormation Template, or the AWS CLI.

Create AWS resources from the AWS management console

Create the AWS resources required for this integration from the AWS user management console.

Create an OpenID Connect provider

In AWS, create an OpenID Connect provider and authenticate Endor Labs to assume roles.

  1. Sign into Identity and Access Management (IAM).
  2. From Access Management, select Identity Providers.
  3. Click Add Provider and choose OpenID Connect.
  4. In Provider URL enter the Endor Labs application URL https://api.endorlabs.com.
  5. Enter an Audience such as endor-aws-code-artifact and click Add Provider.

You must keep the Provider URL and Audience values handy.

Create an IAM role with trust policies

In AWS IAM, create roles that Endor Labs can assume once its users or services are authenticated. Associate each role with a trust policy that grants Endor Labs read-only access to repositories in AWS CodeArtifact.

  1. From IAM, select Roles.
  2. Click Create Role.
  3. From Trusted entity type, select Web Identity and click Next.
  4. Select the Identity provider you created in the previous task and for Audience select the exact value used in the previous task then click Add condition.
  5. Under Add condition set the Key to api.endorlabs.com:sub, set the Condition to StringLike and for the value, input <insert-your-tenant>/*. Make sure to replace <insert-your-tenant> with your tenant name. For example demo/*.
  6. Add one more condition setting Key to api.endorlabs.com:sub, set the Condition to StringLike and for the value, input <insert-your-tenant>.*/*, for example demo.*/* and click Next.
  7. From Permission policies, select AWSCodeArtifactReadOnlyAccess and click Next.
  8. Enter a name for the role such as endor-aws-code-artifact-role and include an optional description.
  9. Review the Select trusted entities section, then click Edit to make modifications if required. It should look like the following example.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Principal": {
                "Federated": "arn:aws:iam::<AWS-Account-ID>:oidc-provider/api.endorlabs.com"
            },
            "Condition": {
                "StringLike": {
                    "api.endorlabs.com:sub": [
                        "<insert-your-namespace>/*",
                        "<insert-your-namespace>.*/*"
                    ]
                },
                "StringEquals": {
                    "api.endorlabs.com:aud": [
                        "endor-aws-code-artifact"
                    ]
                }
            }
        }
    ]
}
  1. Click Create Role.

You must keep the role ARN handy to enter in the Endor Labs application.

You can now go and configure the package manager integration in Endor Labs

Create AWS resources using a CFT template

Use AWS CloudFormation Template (CFT) to automate the creation and configuration of AWS resources required for this integration.

  1. Create a .cft file from the following script entering the OIDC URL, audience, namespace, and role name.
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to create an IAM OpenID Connect (OIDC) identity provider and an IAM role with AWSCodeArtifactReadOnlyAccess.

Parameters:
  OIDCUrl:
    Description: The URL of the OIDC provider (e.g., https://api.endorlabs.com).
    Type: String
    Default: "https://api.endorlabs.com"

  ClientId:
    Description: The audience claim to use in the OIDC trust policy (e.g., endor-aws-code-artifact).
    Type: String
    Default: "endor-aws-code-artifact"

  Namespace:
    Description: The namespace in the OIDC sub claim to allow (e.g., demo).
    Type: String
    Default: "Enter your Endor Labs namespace"

  RoleName:
    Description: IAM role name (e.g., endor-aws-code-artifact-role).
    Type: String
    Default: "endor-aws-code-artifact-role"

Resources:
  OpenIDConnectProvider:
    Type: "AWS::IAM::OIDCProvider"
    Properties:
      Url: !Ref OIDCUrl
      ClientIdList:
        - !Ref ClientId
    DeletionPolicy: Retain

  CodeArtifactRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Ref RoleName
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Federated: !Ref OpenIDConnectProvider  # Directly reference OIDC Provider created in the same template
            Action: "sts:AssumeRoleWithWebIdentity"
            Condition:
              StringEquals:
                "api.endorlabs.com:aud": !Ref ClientId
              StringLike:
                "api.endorlabs.com:sub":
                  - !Sub "${Namespace}/*"
                  - !Sub "${Namespace}.*/*"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AWSCodeArtifactReadOnlyAccess"
    DeletionPolicy: Retain

Outputs:
  TargetRoleArn:
    Description: The ARN of the newly created IAM role
    Value: !GetAtt CodeArtifactRole.Arn

  AllowedAudience:
    Description: The allowed audience
    Value: !Ref ClientId
  1. Save this file with an appropriate name such as awscodeartifact-endor-labs.cft, and have it handy.
  2. Sign into AWS CloudFormation and search for Stacks.
  3. Click Create Stack and select Choose an existing template.
  4. From Template source, select Upload a template file.
  5. Click Choose file, select the file you saved awscodeartifact-endor-labs.cft and click Next.
  6. In Specify stack details, choose a name for the stack, verify the Parameters you entered in the script and click Next.
  7. Select the acknowledgement from Configure stack options and click Next.
  8. From Review and Create, review the details and click Submit. Check the progress of the creation of your resources from Stacks. Once the stack is created, you can see the status as CREATE_COMPLETE.
  9. Click Outputs to see the target role ARN and the AllowedAudience values. Have the values handy to enter in the Endor Labs application.
  10. You can now go and configure the package manager integration in Endor Labs

Create resources from the AWS CLI

To create the necessary resources for CodeArtifact integration with the AWS CLI use the following procedure:

  1. First, create a new OIDC provider in AWS:
aws iam create-open-id-connect-provider \
    --url https://api.endorlabs.com \
    --client-id-list endor-aws-code-artifact
  1. Keep the OpenIDConnectProviderArn returned during the create command handy. If you lose it you can retrieve it using the following command:
aws iam list-open-id-connect-providers
  1. Next, you’ll need to create a role to provide the OIDC provider access to AWS CodeArtifact. Ensure you replace <insert-your-namespace> with your Endor Labs namespace and <insert-your-account-id> with your AWS account ID.
aws iam create-role \
    --role-name endor-aws-code-artifact-role \
    --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<insert-your-account-id>:oidc-provider/api.endorlabs.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "api.endorlabs.com:aud": "endor-aws-code-artifact"
                },
                "StringLike": {
                    "api.endorlabs.com:sub": [
                        "<insert-your-namespace>/*",
                        "<insert-your-namespace>.*/*"
                    ]
                }
            }
        }
    ]
}'
  1. Finally, assign the role a permissions policy to access AWS CodeArtifact.
aws iam attach-role-policy \
    --role-name endor-aws-code-artifact-role \
    --policy-arn arn:aws:iam::aws:policy/AWSCodeArtifactReadOnlyAccess
  1. You can now go and configure the package manager integration in Endor Labs

Configure package manager integration in Endor Labs with AWS CodeArtifact

After creating an IAM role in AWS with the necessary trust policies, configure AWS CodeArtifact package manager integration within the Endor Labs application.

  1. Sign in to Endor Labs and under Manage, select Integrations.
  2. Select the package manager configuration you’d like to customize and click Manage
  3. In the upper right-hand corner, select Add Package Manager.
  4. Select AWS Code Artifactory.
  5. In DOMAIN, enter the name of your repository in AWS CodeArtifact.
  6. In DOMAIN OWNER, enter the AWS account ID that owns the CodeArtifact repository.
  7. In REPOSITORY, enter the repository name.
  8. In TARGET ROLE ARN, enter the role ARN you created.
  9. In ALLOWED AUDIENCE, enter the Audience value specified during role creation. In this example we used endor-aws-code-artifact.
  10. In REGION, enter the AWS region of the AWS Code Artifact Repository.
  11. Select if you want to Propagate this package manager to all child namespaces from Advanced.
  12. Select Add Package Manager.

2 - Set up integrations using webhooks

Learn how to create webhooks and enable custom integrations with Endor Labs application

Webhooks enable real-time communication between different systems or applications over the internet. They allow one application to send data to another application as soon as a specific event or a trigger occurs.

Use webhooks to integrate Endor Labs with applications such as Slack, Microsoft Teams or more, and instantly get notified about projects if your configured policies are violated.

When events are triggered, Endor Labs sends HTTPS POST requests to URLs of your configured events, with all the information you need.

Configure a webhook integration

Set up a custom integration with Endor Labs webhooks.

  1. Sign in to Endor Labs and click Integrations from the sidebar.
  2. Navigate to Webhooks under Notifications and click Add.
  3. Click Add Notification Integration.
  4. Enter a name and description for this integration.
  5. Enter the URL endpoint for the webhooks.
  6. Enter the authentication method such as API Key, Basic, or None.
  7. Enter the details for the authentication method such as USERNAME, PASSWORD, or API KEY. Make sure the API Key has required permissions to post messages using webhook.
  8. To ensure integrity, de-select Disable HMAC Integration Check and enter the HMAC Shared Key. The Hash-Based Message Authentication Code (HMAC) ensures the authenticity of a message using a cryptographic hash function and a secret key. The HMAC signature is passed as a header in the HTTP request.
  9. Click Add Notification Integration.

Endor Labs webhook payload

Endor Labs provides the following webhook payload, that you can customize for your needs.

Name Description
data.message Brief message about the number of findings discovered for a project
data.project_url Link to the scanned project in the Endor Labs application
data.policy.name Name of the violated policy that triggered the notification
data.policy.url Link to the violated policy in the Endor Labs application
data.findings Complete list of findings
data.findings[].uuid Unique identifier of the finding
data.findings[].description Brief description of the finding
data.findings[].severity Severity of the finding
data.findings[].dependency [CONDITIONAL] Name of dependency that caused the policy violation. This field is only present for findings that have a dependency associated. For example, vulnerability findings
data.findings[].package [CONDITIONAL] The version of the package in the project that imported the dependency causing the policy violation. This field is only present for findings that have a package version associated with them. For example, vulnerability findings
data.findings[].repositoryVersion [CONDITIONAL] Repository version of the project that triggered the policy violation. This field is only present for findings that have a repository version associated with them. For example, secrets findings
data.findings[].findingURL Link to the finding in the Endor Labs application

You can view all possible payload information in GetFindings REST API endpoint. Expand the spec section in the API response to view all the information. Example:

See the following example for a sample notification payload.

{
 "data": {
  "message": "6 findings discovered for project endorlabs/monorepo",
  "projectURL": "https://localhost:8082/t/endor/projects/65e5b83466145505541d9664",
  "policy": {
   "name": "Webhook vuln",
   "url": "https://localhost:8082/t/endor/policies/actions?filter.default=Webhook+vuln"
  },
  "findings": [
   {
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "description": "GHSA-c2qf-rxjj-qqgw: semver vulnerable to Regular Expression Denial of Service",
    "severity": "FINDING_LEVEL_MEDIUM",
    "dependency": "semver@7.5.0",
    "package": "endorlabs-vscode-extension@1.5.0",
    "findingURL": "https://localhost:8082/t/endor/findings/6614ec9141aef3ab8e90ed80"
   },
   {
    "uuid": "550e8400-e29b-41d4-a716-446655440001",
    "description": "GHSA-c2qf-rxjj-qqgw: semver vulnerable to Regular Expression Denial of Service",
    "severity": "FINDING_LEVEL_MEDIUM",
    "dependency": "semver@7.3.8",
    "package": "endorlabs-vscode-extension@1.5.0",
    "findingURL": "https://localhost:8082/t/endor/findings/6614ec9141aef3ab8e90ed81"
   },
   {
    "uuid": "550e8400-e29b-41d4-a716-446655440002",
    "description": "GHSA-c2qf-rxjj-qqgw: semver vulnerable to Regular Expression Denial of Service",
    "severity": "FINDING_LEVEL_MEDIUM",
    "dependency": "semver@5.7.1",
    "package": "endorlabs-vscode-extension@1.5.0",
    "findingURL": "https://localhost:8082/t/endor/findings/6614ec9141aef3ab8e90ed82"
   },
   {
    "uuid": "550e8400-e29b-41d4-a716-446655440003",
    "description": "GHSA-c2qf-rxjj-qqgw: semver vulnerable to Regular Expression Denial of Service",
    "severity": "FINDING_LEVEL_MEDIUM",
    "dependency": "semver@6.3.0",
    "package": "endorlabs-vscode-extension@1.5.0",
    "findingURL": "https://localhost:8082/t/endor/findings/6614ec9141aef3ab8e90ed83"
   }
  ]
 }
}

Use Endor Labs webhooks to integrate with Slack

If you use Slack as a collaborative tool, integrate Slack channels using webhooks in Endor Labs to publish notifications as messages in the respective channels.

Create incoming webhooks in Slack

Create an incoming webhook to your Slack channel to enable Endor Labs to post notifications in the channel. The webhook provides a unique URL which is used to integrate the channel in Endor Labs. To send messages into Slack using incoming webhooks, see Slack Integration.

If you have already created an incoming webhook in the channel, copy the unique URL and integrate the channel in Endor Labs.

Customize webhook notification templates

Endor Labs provides you with a default template with standard information that will be included in the webhook message. You can use the default template or you can choose to edit and customize this template to fit your organization’s specific requirements. You can also create your own custom templates using Go Templates.

  1. Sign into Endor Labs and navigate to Manage>Integrations
  2. Look for Slack under Notifications.
  3. Click Manage to view the list of configured notification integrations.
  4. Choose one and click the ellipsis on the right side, and click Edit Template.
  5. Make required changes to any of the following templates and click Save Template.
    • Open - This template is used when new notifications are raised.
    • Update - This template is used when an existing notification is updated, such as, when some findings for the notification are changed.
    • Resolve - This template is used when all the findings reported by the notification are resolved.
  6. Click Restore to Default to revert the changes.
  7. Use the download icon on the top right corner to download this template.
  8. Use the copy icon to copy the information in the template.

Data model

To create custom templates for Webhook notifications, you must understand the data supplied to the template.

See the protobuf specification NotificationData message used for the templates.

syntax = "proto3";

package internal.endor.ai.endor.v1;

import "google/protobuf/wrappers.proto";
import "spec/internal/endor/v1/finding.proto";
import "spec/internal/endor/v1/notification.proto";
import "spec/internal/endor/v1/package_version.proto";
import "spec/internal/endor/v1/project.proto";
import "spec/internal/endor/v1/repository_version.proto";

option go_package = "github.com/endorlabs/monorepo/src/golang/spec/internal.endor.ai/endor/v1";
option java_package = "ai.endor.internal.spec";

// The statistics for findings in a notification.
message FindingStats {
  // The total number of findings for a notification.
  google.protobuf.UInt32Value num_total_findings = 1;
  google.protobuf.UInt32Value num_total_critical_severity_findings = 2;
  google.protobuf.UInt32Value num_total_high_severity_findings = 3;
  google.protobuf.UInt32Value num_total_medium_severity_findings = 4;
  google.protobuf.UInt32Value num_total_low_severity_findings = 5;

  // The number of new findings for a notification as compared to the previous scan.
  google.protobuf.UInt32Value num_new_findings = 6;
  google.protobuf.UInt32Value num_new_critical_severity_findings = 7;
  google.protobuf.UInt32Value num_new_high_severity_findings = 8;
  google.protobuf.UInt32Value num_new_medium_severity_findings = 9;
  google.protobuf.UInt32Value num_new_low_severity_findings = 10;

  // The number of findings for a notification that was resolved in latest scan.
  google.protobuf.UInt32Value num_resolved_findings = 11;
}

// The data supplied to notification templates while rendering.
message NotificationData {
  // The raw notification object.
  Notification raw_notification = 1;

  // The name of the project.
  google.protobuf.StringValue project_name = 2;

  // The name of the violated policy that triggered the notification.
  google.protobuf.StringValue policy_name = 3;

  // The Git reference of the project that was scanned.
  google.protobuf.StringValue ref_name = 4;

  // The project URL.
  google.protobuf.StringValue project_url = 5;

  // The map of finding UUIDs to finding objects.
  map<string, internal.endor.ai.endor.v1.Finding> findings_map = 6;

  // The map of finding UUIDs to corresponding parent package version objects.
  map<string, internal.endor.ai.endor.v1.PackageVersion> package_version_map = 7;

  // The map of finding UUIDs to corresponding parent project objects.
  map<string, internal.endor.ai.endor.v1.Project> project_map = 8;

  enum NotificationType {
    NOTIFICATION_TYPE_UNSPECIFIED = 0;

    // Notification type when a notification is created.
    NOTIFICATION_TYPE_CREATE = 1;

    // Notification type when a notification is updated.
    NOTIFICATION_TYPE_UPDATE = 2;

    // Notification type when a noticiation is resolved.
    NOTIFICATION_TYPE_RESOLVED = 3;
  }

  NotificationType type = 9;

  // The project to which the notification is associated.
  internal.endor.ai.endor.v1.Project project = 10;

  // The map of finding UUIDs to the correcponding parent repository version objects.
  map<string, internal.endor.ai.endor.v1.RepositoryVersion> repository_version_map = 11;

  // The project URL in Endor Labs UI.
  google.protobuf.StringValue project_app_url = 12;

  // The policy URL in Endor Labs UI.
  google.protobuf.StringValue policy_app_url = 13;

  FindingStats finding_stats = 14;

  // The map of package version UUIDs to package version names.
  map<string, string> package_version_name_map = 15;
}

To understand Project, Finding, PackageVersion and RepositoryVersion definitions used in this protobuf specification, see:

See the following specification to understand a few additional functions available to the template. You can access these functions by using their corresponding keys.


// FuncMap contains the additional functions that are available to notification templates.
var FuncMap = func(h *NotificationTemplate) template.FuncMap {
	return template.FuncMap{
		"now": func() string {
			now := time.Now()
			utc := now.UTC()
			return utc.Format("01-02-2006 15:04:05")
		},

		// csvFileName generates the filename for the CSV attachment for Jira.
		"csvFileName": GetJiraAttachmentFilename,

		// findingURL returns the URL for the given finding.
		"findingURL": h.getFindingURL,

		// toCSV converts the given string to a CSV format.
		"toCSV": toCSV,

		// findingLevelSlackEmoji returns the slack emoji for the given finding based on severity.
		"findingLevelSlackEmoji": GetSlackEmojiForSeverity,

		// packageName returns the user facing name of the package.
		"packageName": func(p *endorpb.PackageVersion) string {
			return lib.GetUserFacingName(p.GetMeta().GetName().GetValue())
		},

		// filteredFindingsURL returns the URL to view findings with the given uuids
		"filteredFindingsURL": common.GetFilteredFindingsURL,

		// increment increments the given integer by 1.
		"increment": func(i int) int {
			return i + 1
		},
	}
}

Webhook handler example for Slack

Create a webhook handler or a cloud function to receive webhook requests generated by Endor Labs, authorize the request, and post messages to your Slack channel.

See the following code sample hosted as a cloud function or a webhook handler.

// Package p contains an HTTP Cloud Function.
package p

import (
 "encoding/json"
 "fmt"
 "html"
 "io"
 "io/ioutil"
 "bytes"
 "log"
 "net/http"
 "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "strings"
 wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
)

// Struct representation of default webhook payload from Endor Lab's notification.
type WebhookMessage {
 Data Payload `json:"data"`
}

type Payload struct {
 Message string  `json:"message"`
 ProjectUrl string  `json:"projectURL"`
 Policy  Policy  `json:"policy"`
 Findings []Finding `json:"findings"`
}

type Finding struct {
 Uuid string `json:"uuid"`
 Description string `json:"description"`
 Severity string `json:"severity"`
 Dependency string `json:"dependency,omitempty"`
 Package string `json:"package,omitempty"`
 RepositoryVersion string `json:"repositoryVersion,omitempty"`
 FindingUrl string `json:"findingURL"`
}

type Policy struct {
 Name string `json:"name"`
 Url string `json:"url"`
}

// HelloWorld deserializes the default webhook payload from the notification object,
// formats it into a format that Slack supports and send the message to Slack via webhook.
func HelloWorld(w http.ResponseWriter, r *http.Request) {
 var d WebhookMessage

 if err := json.NewDecoder(r.Body).Decode(&d); err != nil {
  switch err {
  case io.EOF:
   log.Printf("success")
   return
  default:
   log.Printf("json.NewDecoder: %v", err)
   http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
   return
  }
 }

 // Perform the HMAC sign to make sure that the request is not tampered with.
 hmacSign := ""
 for headerName, headerValues := range r.Header {
  if headerName == "X-Endor-Hmac-Signature" {
   if headerValues[0] == "" {
    http.Error(w, "hmac empty", http.StatusUnauthorized)
    return
   }
   hmacSign = headerValues[0]
  }
 }

 receivedMessage := d.Message
 // Secret configured in Endor
    secretKey := "Secret"

    // Validate the HMAC
    isValid := validateHMAC(receivedMessage, hmacSign, secretKey)

    // Process the result
    if isValid {
      fmt.Fprint(w, html.EscapeString("success"))
    } else {
       http.Error(w, "unauthorized, something changed", http.StatusUnauthorized)
  return
    }

 textToSlack := fmt.Sprintf("%s which violates policy %s", d.Data.Message, d.Data.Policy.Name)
 sendMessageToSlack(textToSlack)

}


func validateHMAC(receivedMessage, receivedHMAC, secretKey string) bool {
    // Create a new HMAC hasher using the SHA-256 hash function and the secret key
    mac := hmac.New(sha256.New, []byte(secretKey))

    // Write the received message to the HMAC hasher
    mac.Write([]byte(receivedMessage))

    // Calculate the HMAC value
    expectedHMAC := mac.Sum(nil)

    // Convert the expected HMAC to a hexadecimal string
    expectedHMACString := hex.EncodeToString(expectedHMAC)

    // Compare the expected HMAC with the received HMAC (ignoring case)
    return strings.EqualFold(receivedHMAC, expectedHMACString)
}

func sendMessageToSlack(msg string) {
    // Replace this url with the url hook from the Slack App
 url := "https://slack.webhook"

 payload := []byte(`{"text": "Hey there are findings in project https://github.com/endorlabs/python-deps.git which violates policy DemoNotification"}`)

 req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
 if err != nil {
  fmt.Println("Error creating request:", err)
  return
 }

 req.Header.Set("Content-Type", "application/json")

 client := &http.Client{}
 resp, err := client.Do(req)
 if err != nil {
  fmt.Println("Error sending request:", err)
  return
 }
 defer resp.Body.Close()

 body, err := ioutil.ReadAll(resp.Body)
 if err != nil {
  fmt.Println("Error reading response body:", err)
  return
 }
}

3 - Set up Microsoft Defender for Cloud integration with Endor Labs

Learn how to integrate Defender for Cloud with Endor Labs to close the gap between Application and Cloud security.

Defender for Cloud, a Cloud-Native Application Protection Platform (CNAPP), provides comprehensive security for hybrid-cloud and multi-cloud environments. It offers advanced threat protection, security posture management, and seamless integration with development workflows. Integrate Defender for Cloud with Endor Labs to mature your security programs. With reachability analysis available directly within the Defender for Cloud console, you can prioritize what to fix based on exploitability without needing to switch tools. And with attack paths showing everywhere vulnerable code is running throughout the SDLC and in the cloud, you have a new way prioritize which vulnerabilities to remediate first.

You can correlate SCA findings with runtime alerts to view code-to-runtime attack paths. You can trace vulnerabilities found in open source software (OSS) dependencies directly to potential exploit paths in cloud environments. This allows you to prioritize remediation efforts more effectively and reduce risk across the entire software development lifecycle.

Code-to-runtime context also reveals toxic combinations of security issues. For example, there is a reachable vulnerability in an open source package, which is used on an internet reachable cloud workload. You can see a full attack path, from code committed to Azure DevOps, GitHub, or GitLab, to runtime workloads deployed on Azure, AWS, or Google Cloud Platform.

Prerequisites

Complete the prerequisites in Endor Labs and Defender for Cloud before you can configure the integration.

Prerequisites in Endor Labs

Ensure that you complete the prerequisites in Endor Labs so that your environment is set up properly to provide findings to Defender for Cloud.

Prerequisites in Defender for Cloud

Complete the prerequisites in Defender for Cloud so that your environment is properly set up so that your repositories are properly set up for integration, and you have sufficient permissions to manage the integration with Endor Labs.

  • Enable Defender CSPM on the subscription where you wish to see code-to-runtime contextualization.

  • A user with Security Administrator or Global Administrator permissions on the tenant to create the connector to Endor Labs.

  • Add repositories that you want to monitor in the tenant.

    Contributor or Security Admin permissions on an Azure subscription to create DevOps connectors to Azure DevOps or GitHub.

    For Azure DevOps, Project Collection Administrator is required to onboard the organization.

    For GitHub, Owner is required to onboard the organization.

  • To monitor results, provide a user with at least Security Reader or Reader permissions on the subscription with the DevOps connector.

  • To view the attack paths and code-to-runtime capabilities, the container registry can be in Azure, AWS, GCP, or Docker Hub. The Kubernetes cluster can be in Azure, AWS, or GCP.

    If you use Azure Kubernetes Cluster (AKS) and Azure Container Registry (ACR) with an admin account in the Azure subscription. The ACR must be attached to the AKS so that you can deploy images from ACR to AKS.

Configure Defender for Cloud integration

You need to configure the integration in Defender for Cloud.

  1. In Defender for Cloud, navigate to Management > Environment Settings.

  2. Select Add Integration > Endor Labs.

  3. Enter a name for the integration.

  4. Enter the following information from your Endor Labs environment when you configure the integration:

  5. Click Save.

Once the integration is set up, Endor Labs data is available in Defender for Cloud.

Prioritize findings by exploitability

From the Defender for Cloud console, you can use Endor Labs’ function-reachability analysis to prioritize what to fix based on exploitability.

  1. Select General > Cloud Security Explorer.

  2. Select Query Builder.

  3. Build a query that searches code repositories that have vulnerabilities with reachable functions.

    Defender for Cloud Query Builder

  4. Click Search to list results based on the search query.

    Defender for Cloud Search Results

  5. Select a repository to view more details on the vulnerabilities.

    Defender for Cloud Result Details

    You can review the findings and also navigate to Endor Labs UI to view more information on the findings.

Detect vulnerable code running in the cloud

From the Defender for Cloud console, you can view an attack path that visualizes everywhere vulnerable code is running throughout the SDLC and in the cloud.

Select General > Attack Path Explorer to view an attack path of vulnerable code running in a cluster.

4 - Set up Jira integration with Endor Labs

Learn how to implementing ticketing workflows for JIRA.

Integrate Endor Labs with Jira and automatically create Jira tickets in specific projects when configured policies are violated. This integration automates the process of generating Jira tickets within your organization’s existing security workflow. This integration is supported on Jira Cloud.

To integrate Endor Labs with Jira:

Generate Jira API token

Generate Jira API credentials that you want to use to sign in to Endor Labs.

Note: It is recommended that the Jira account used for this integration includes only the following set of minimum required permissions.

  • Create Issues
  • Transition Issues
  • Assign Issues
  • Resolve Issues
  • Add Comments
  1. Sign into your Jira account.
  2. Navigate to your Jira profile.
  3. Under API tokens, click Create API Token.
  4. Enter a concise label to distinguish your token and click Create.
  5. Click Copy to clipboard, and have the token handy to enter in the Endor Labs application.

Note: The token cannot be viewed after closing the form. Copy it to a secure location and have it handy. Do not share the token.

Configure Jira Integration on Endor Labs

Set up Jira integration on the Endor Labs application.

  1. Sign in to Endor Labs.
  2. From the sidebar, navigate to Integrations.
  3. Under Notifications, click Manage for Jira.
  4. Click Add Notification Integrations.
  5. Enter a name and description for the integration.
  6. Enter a Jira user name. The user account is displayed as the reporter for all the tasks or bugs created in Jira for this notification.
  7. In API Key, enter the API token that you generated from Jira.
  8. In Jira URL, enter the HTTPS endpoint of your Jira instance.
  9. In PROJECT Key, enter the project key in which you want to create the Jira notifications. The project key is the prefix of the bug or task ID. For example, if the project key is ABC, the task or bug is created with ID in the format ABC-xxx.
  10. In ISSUE TYPE, enter the notification issue type such as Task, Bug, Story, Sub-Task, or Epic. The issue type is case-sensitive. Make sure to match with an exact issue type on your Jira board.
  11. In RESOLVED STATUS, specify the resolved status used in your Jira projects. For example, Completed. After the findings are resolved, the Jira ticket will be updated to this status. If you don’t specify a status, Endor Labs will attempt to determine your project’s resolution status and default to one of the following, in order of priority: Done, Resolved, Closed, or Fixed.
  12. In LABELS, enter a label and associate it with your Jira notifications.
  13. Click Add Custom Field to add custom KEY-VALUE pairs in the created Jira ticket. For example, you can add KEY as Source and associate it to Endor Labs in VALUE, so that every notification created will now have the information Source = Endor Labs associated with the ticket.
  14. Click Propagate this notification target to all child namespaces to apply this Jira notification target to all child namespaces within the hierarchy.
  15. Click Add Notification Integration.

Manage Endor Labs Jira notifications

You can view and manage the Endor Labs Jira notifications created for a project.

  1. From the sidebar, navigate to Integrations.
  2. Under Notifications, click Manage for Jira.
  3. To edit a notification, click the vertical ellipsis and choose Edit Notification Integration.
  4. To delete a notification, click the vertical ellipsis dots and choose Delete Notification Integration.

Associate an action policy with a Jira notification

Users can create action policies to execute a recommended action when a policy is violated. For example, if there is a license compliance violation, you can create a Jira ticket and notify the required personnel.

While creating an action policy, configure the following settings:

  • Select Choose an Action as Send Notification.
  • From SELECT NOTIFICATION TARGETS, choose the Jira integration notification that you created.
  • Choose an Aggregation type for Jira notifications. Choose Project to trigger a single notification for all findings, or choose Dependency to trigger multiple notifications for every dependency. See Aggregation types for more details.

A parent ticket is created with the selected issue type, either Task or Bug. The parent ticket includes the project name. Each identified dependency is grouped under a dedicated sub-ticket. The sub-ticket includes both the project name and dependency name. Findings without any dependency are grouped in a separate sub-ticket. During future scans, the existing sub-ticket status is updated or resolved. If a new dependency is found, a new sub-ticket is created.

Jira ticket

View Jira ticket details

Users can view the created Jira ticket details on the Endor Labs application. Users have the ability to observe specific information such as the status of tickets (whether they are open or closed), the associated action policy, the number of violations, and other important details. This aids in seamless troubleshooting and identification of both unresolved and resolved issues.

  1. From the Endor Labs application, navigate to Manage and click Notifications.
  2. Navigate across the Open, Resolved, or All tabs to view the issues listed under them.
  3. You can view specific details such as created date of the ticket, the name of the policy, the name of the project, the number of violations, and any labels associated with the projects.
  4. Choose a notification and click the vertical three dots on the far right side and choose:
    • Dismiss Notification: Clear this notification if it is no longer valid. It will be marked in grey.
    • Show Details: View the Jira ticket number and you can also navigate to Jira.
    • Go to Policy: View configuration details of the policy that created this Jira ticket.

5 - Set up Vanta integration with Endor Labs

Learn how to integrate Vanta with Endor Labs and automate compliance requirements

Vanta enables organizations to manage risk by automating compliance and streamlining security reviews. Integrate Vanta with Endor Labs to view security findings in real-time and accelerate your security audit processes.

To integrate Endor Labs with Vanta:

Create an application in Vanta

Create an application in Vanta so that Endor Labs can authenticate and export vulnerability findings to Vanta. The app requires connectors.self:write-resource and connectors.self:read-resource scopes to export vulnerabilities.

  1. Sign in to Vanta as an Administrator.
  2. Click Settings on the top navigation bar.
  3. Select Developer Console. Vanta Developer Console
  4. Click Create.
  5. Select Build Integrations.
  6. Enter a name and description for your application.
  7. Select the App Visibility as Private and click Create. Create Vanta Integration
  8. Select the Application Category as Vulnerability Scanner.
  9. Click Generate Client Secret to generate the OAuth client secret. OAuth Client ID appears. Copy the OAuth Client ID and the client secret and have them handy. You must enter this data in Endor Labs to configure the Vanta integration. Build Vanta Integration
  10. Click Save.

Create resources in Vanta

To successfully ingest security data and create notifications, map the Endor Labs attributes to resource types in Vanta.

  1. Sign in to Vanta.

  2. Navigate to Settings and click Developer Console.

  3. Select your application and click Resources.

  4. Click Create Resource and create the following resources to successfully map Endor Labs data into Vanta.

    • Enter the Resource Type as Vulnerable Component (mandatory) and select the Base Resource Type as VulnerableComponent. Create Resource
    • Enter the Resource Type as Package Vulnerability (optional) and select the Base Resource Type as PackageVulnerabilityConnectors.
    • Enter the Resource Type as Static Code Analysis (optional) and select the Base Resource Type as StaticAnalysisCodeVulnerabilityConnectors.

    Provide the Static Code Analysis resource type if you want to export exposed secrets in your first party code to Vanta.

    You can view the schema generated for all the resource types.

Copy the Resource ID of the generated resources and have them handy. You must enter this data in Endor Labs to configure the Vanta integration. Vanta Resource IDs

Configure Vanta integration

Set up Endor Labs integration with Vanta.

Prerequisites: Make sure you have the client ID, client secret, and the resource IDs from Vanta handy.

  1. Sign in to Endor Labs and click Integrations from the sidebar.
  2. Under Notifications, click Add for Vanta.
  3. Click Add Notification Integration. Add Notification Integration
  4. Enter a name and description for this integration.
  5. Enter the CLIENT ID and CLIENT SECRET that you generated on Vanta.
  6. Under Vanta Resources, enter the Resource IDs for VULNERABILITY COMPONENT, PACKAGE VULNERABILITY, and STATIC CODE ANALYSIS VULNERABILITY from Vanta.
  7. Click Add Notification Integration.

Associate an action policy with a Vanta notification

Users can create action policies to execute a recommended action when a policy is violated. For example, if there is a critical or high vulnerability, those vulnerabilities are exported to Vanta to ensure compliance adherence.

While creating an action policy, configure the following settings:

  • Select Choose an Action as Send Notification.
  • From SELECT NOTIFICATION TARGETS, choose the Vanta integration notification that you created.
  • Choose an Aggregation type for notifications. For integrating with Vanta, we recommend you choose Project.
  • From Assign Scope, include the project tags in INCLUSIONS to apply this policy to a project.

See Create an action policy for more details.

Manage Vanta notification targets in Endor Labs

You can view and manage the Endor Labs Vanta notification targets created for a project.

  1. From the sidebar, navigate to Manage > Integrations.
  2. Under Notifications, click Manage for Vanta. You can view all your created notification targets for Vanta.
  3. To edit a notification target, click the vertical ellipsis and choose Edit Notification Integration.
  4. To delete a notification target, click the vertical ellipsis dots and choose Delete Notification Integration.

Run a scan

Run the endorctl scan on your configured projects. See endorctl scan commands for more information.

Findings exported to Vanta

Endor Labs sends the following findings to Vanta:

  • third-party open-source vulnerabilities
  • secrets exposed in the first-party code

These findings are exported as Package Vulnerabilities and Static Code Analysis Vulnerabilities in Vanta. They are associated with a Vulnerable Component (that is the Repository Version) in Vanta.

Exporting findings generated on the Git repository security posture of an organization are not supported.

View findings in Vanta

View Endor Labs’ findings in Vanta and take remedial actions.

  1. Sign in to Vanta.
  2. Select Tests to view notifications.
  3. Select the integration that you created in the Integration filter to view notifications from Endor Labs. View Endor Labs Results in Vanta
  4. Select a notification to view all findings associated with the Endor Labs policy. View notification in Vanta
  5. Click on a finding to view more details in Endor Labs.

For example, if you create an action policy to notify critical vulnerabilities and configure it to a Vanta notification target, you can see the exports as Critical vulnerabilities identified in code repositories are addressed under Tests in Vanta. The test classifications are based on the severity of the exported findings.

6 - Set up email integration

Learn how to integrate your email addresses with Endor Labs and receive finding notifications

Integrate your email address with Endor Labs and automatically receive policy violations as email notifications.

Configure email integration

To configure an email integration, follow these steps:

  1. Sign in to Endor Labs and click Integrations from the left sidebar.
  2. Navigate to Email under Notifications and click Add.
  3. Click Add Notification Integration.
  4. Specify a name and description for this integration.
  5. Enter email addresses separated by commas in EMAIL ADDRESSES.
  6. Click Add Notification Integration.

Associate an action policy with the email notification

Users can create action policies to send an email notification when the conditions of a given policy are met. For example, if there is a critical or high vulnerability, send an email notification.

While creating an action policy, configure the following settings:

  • Select Choose an Action as Send Notification.
  • From SELECT NOTIFICATION TARGETS, choose the email integration notification that you created.
  • Choose an Aggregation type for notifications.
    • Choose Project to group and send the findings related to a project in one email.
    • Choose Dependency to send individual email messages for every dependency.
  • From Assign Scope, include the project tags in INCLUSIONS to apply this policy to a project.

See Create an action policy for more details.

Customize email notification templates

Endor Labs provides a default template with standard information that will be included in the email. You can use the default template or you can choose to edit and customize this template to fit your organization’s specific requirements. You can also create custom templates using Go Templates.

  1. Sign in to Endor Labs and navigate to Manage > Integrations.
  2. Look for Email under Notifications.
  3. Click Manage to view the list of configured notification integrations.
  4. Choose a notification integration and click the ellipsis on the right side, and click Edit Template.
  5. Make required changes to any of the following templates and click Save Template.
    • Open - This template is used when new notifications are raised.
    • Update - This template is used when an existing notification is updated, such as, when some findings for the notification are changed.
    • Resolve - This template is used when all the findings reported by the notification are resolved.
  6. Click Restore to Default to revert the changes.
  7. Use the download icon on the top right corner to download this template.
  8. Use the copy icon to copy the information in the template.

Data model

To create custom templates for email notifications, you must understand the data supplied to the template.

See the EmailData message used for Open and Update templates.


// EmailData contains mappings for findings and package versions that is to be published as
// an email. It also contains the NotificationData object in the payload.
type EmailData struct {
	Payload                      *endorpb.NotificationData
	PackageVersionFindingMapping map[string]map[string][]string
	PackageVersionMap            map[string]*endorpb.PackageVersion
	APIURL                       string
	APPURL                       string
	FromAddress                  string
}

See the ResolvedEmailData message used for Resolve template.


// ResolvedEmailData contains the data that's acessible in the resolved email template.
type ResolvedEmailData struct {
	APIURL      string
	APPURL      string
	Project     *endorpb.Project
	Policy      *endorpb.Policy
	ProjectName string
}

See the following protobuf specification for the NotificationData message referenced by EmailData.

syntax = "proto3";

package internal.endor.ai.endor.v1;

import "google/protobuf/wrappers.proto";
import "spec/internal/endor/v1/finding.proto";
import "spec/internal/endor/v1/notification.proto";
import "spec/internal/endor/v1/package_version.proto";
import "spec/internal/endor/v1/project.proto";
import "spec/internal/endor/v1/repository_version.proto";

option go_package = "github.com/endorlabs/monorepo/src/golang/spec/internal.endor.ai/endor/v1";
option java_package = "ai.endor.internal.spec";

// The statistics for findings in a notification.
message FindingStats {
  // The total number of findings for a notification.
  google.protobuf.UInt32Value num_total_findings = 1;
  google.protobuf.UInt32Value num_total_critical_severity_findings = 2;
  google.protobuf.UInt32Value num_total_high_severity_findings = 3;
  google.protobuf.UInt32Value num_total_medium_severity_findings = 4;
  google.protobuf.UInt32Value num_total_low_severity_findings = 5;

  // The number of new findings for a notification as compared to the previous scan.
  google.protobuf.UInt32Value num_new_findings = 6;
  google.protobuf.UInt32Value num_new_critical_severity_findings = 7;
  google.protobuf.UInt32Value num_new_high_severity_findings = 8;
  google.protobuf.UInt32Value num_new_medium_severity_findings = 9;
  google.protobuf.UInt32Value num_new_low_severity_findings = 10;

  // The number of findings for a notification that was resolved in latest scan.
  google.protobuf.UInt32Value num_resolved_findings = 11;
}

// The data supplied to notification templates while rendering.
message NotificationData {
  // The raw notification object.
  Notification raw_notification = 1;

  // The name of the project.
  google.protobuf.StringValue project_name = 2;

  // The name of the violated policy that triggered the notification.
  google.protobuf.StringValue policy_name = 3;

  // The Git reference of the project that was scanned.
  google.protobuf.StringValue ref_name = 4;

  // The project URL.
  google.protobuf.StringValue project_url = 5;

  // The map of finding UUIDs to finding objects.
  map<string, internal.endor.ai.endor.v1.Finding> findings_map = 6;

  // The map of finding UUIDs to corresponding parent package version objects.
  map<string, internal.endor.ai.endor.v1.PackageVersion> package_version_map = 7;

  // The map of finding UUIDs to corresponding parent project objects.
  map<string, internal.endor.ai.endor.v1.Project> project_map = 8;

  enum NotificationType {
    NOTIFICATION_TYPE_UNSPECIFIED = 0;

    // Notification type when a notification is created.
    NOTIFICATION_TYPE_CREATE = 1;

    // Notification type when a notification is updated.
    NOTIFICATION_TYPE_UPDATE = 2;

    // Notification type when a noticiation is resolved.
    NOTIFICATION_TYPE_RESOLVED = 3;
  }

  NotificationType type = 9;

  // The project to which the notification is associated.
  internal.endor.ai.endor.v1.Project project = 10;

  // The map of finding UUIDs to the correcponding parent repository version objects.
  map<string, internal.endor.ai.endor.v1.RepositoryVersion> repository_version_map = 11;

  // The project URL in Endor Labs UI.
  google.protobuf.StringValue project_app_url = 12;

  // The policy URL in Endor Labs UI.
  google.protobuf.StringValue policy_app_url = 13;

  FindingStats finding_stats = 14;

  // The map of package version UUIDs to package version names.
  map<string, string> package_version_name_map = 15;
}

To understand Project, Finding, PackageVersion and RepositoryVersion definitions that are used in this protobuf specification, see:

See the following specification to understand a few additional functions available to the template. You can access these functions by using their corresponding keys.


// EmailTemplateFuncs contains the functions that are available in the email template.
var EmailTemplateFuncs = template.FuncMap{
	"now": func() string {
		now := time.Now()
		utc := now.UTC()
		return utc.Format("01-02-2006 15:04:05")
	},

	// findingURL returns the URL for the finding.
	"findingURL": func(f *endorpb.Finding, apiURL string) string {
		findingURL, err := common.GetFindingURL(apiURL, f)
		if err != nil {
			return ""
		}
		return findingURL
	},

	"getGitImage": func(url string) string {
		if strings.HasPrefix(url, "https://github.com") {
			return "github.png"
		}
		if strings.HasPrefix(url, "https://gitlab.com") {
			return "gitlab.png"
		}
		return "default_host.png"
	},

	"getProjectURL": func(p *endorpb.Project, apiURL string) string {
		projectURL, err := common.GetProjectURL(apiURL, p)
		if err != nil {
			return ""
		}
		return projectURL
	},

	"getPackageVersionURL": func(p *endorpb.PackageVersion, apiURL string) string {
		packageVersionURL, err := common.GetPackageVersionURL(apiURL, p)
		if err != nil {
			return ""
		}
		return packageVersionURL
	},

	"getFindingLevel": func(f *endorpb.Finding) string {
		return f.GetSpec().GetLevel().String()
	},

	"isPatchAvailable": func(f *endorpb.Finding) bool {
		for _, tag := range f.GetSpec().GetFindingTags() {
			if tag == endorpb.FindingTags_FINDING_TAGS_FIX_AVAILABLE {
				return true
			}
		}
		return false
	},

	"getPackageEcosystem": func(p *endorpb.PackageVersion) string {
		if p == nil {
			return "unspecified"
		}

		offset := len("ECOSYSTEM_")
		ecosystem := p.GetSpec().GetEcosystem().String()[offset:]
		ecosystem = strings.ToLower(ecosystem)
		return ecosystem
	},
}

Run a scan

Run the endorctl scan on your configured projects. See endorctl scan commands for more information. You can view email notifications of policy violations in your inbox.

7 - Set up Slack integration

Learn how to integrate Slack with Endor Labs and receive finding notifications

Integrate Endor Labs with Slack and automatically receive policy violations as notifications in your Slack channels. If you are using Slack for team communication and notifications, this integration helps you to seamlessly integrate Endor Labs into your organization’s existing workflows.

Create incoming webhooks in Slack

Create an incoming webhook to your Slack channel to enable Endor Labs to post notifications in the channel. The Incoming Webhook provides a unique URL to integrate your Slack channel in Endor Labs.

To create incoming webhooks in Slack:

  1. Create a Slack app for Endor Labs or use an existing app.
    • Click Create New App.
    • Choose From Scratch and Enter a name for the app, for example, Endor Labs.
    • Select your workspace and click Create App
    • You can enter basic, install, or display information for your Endor Labs app in Slack.
    • In Display Information, you can upload a logo and customize App colours to distinguish the Endor Labs App on the Slack workspace.
    • Click Save Changes.
  2. Navigate to Features, select Incoming Webhooks, and toggle Activate Incoming Webhooks.
  3. Refresh the page and click Add New Webhook to Workspace.
  4. Select a channel to receive Endor Labs findings in Post to, then select Authorize. If you need to add the incoming webhook to a private channel, you must first be in that channel.
  5. From Settings, copy the webhook URL under Webhook URLs for Your Workspace. Keep this URL handy to enter in Endor Labs.

For details on creating incoming webhooks in Slack, see Slack Integration.

Configure Slack integration

To configure Slack integration, follow these steps:

  1. Sign in to Endor Labs and click Integrations from the left sidebar.
  2. Navigate to Slack under Notifications and click Add.
  3. Click Add Notification Integration.
  4. Specify a name and description for this integration.
  5. Enter webhook URL copied from Slack in Incoming Webhook.
  6. Click Add Notification Integration.

Associate an action policy with a Slack notification

Users can create action policies to send a Slack notification when the conditions of a given policy are met. For example, if there is a critical or high vulnerability, send the findings to Slack.

While creating an action policy, configure the following settings:

  • Select Choose an Action as Send Notification.
  • From SELECT NOTIFICATION TARGETS, choose the Slack integration notification that you created.
  • Choose an Aggregation type for notifications.
    • Choose Project to group and send the findings related to a project in one message. You can see the top 3 findings by their severity level.
    • Choose Dependency to send individual messages for every dependency. You can see the top 3 findings by their severity level.
  • From Assign Scope, include the project tags in INCLUSIONS to apply this policy to a project.

See Create an action policy for more details.

Manage Slack notification targets in Endor Labs

You can view and manage the Endor Labs Slack notification targets created for a project.

  1. From the sidebar, navigate to Manage > Notifications.
  2. Under Notifications, click Manage for Slack. You can view all your created notification targets for Slack.
  3. To edit a notification target, click the vertical ellipsis and choose Edit Notification Integration.
  4. To delete a notification target, click the vertical ellipsis dots and choose Delete Notification Integration.

Customize Slack notification templates

Endor Labs provides a default standard template with standard information that will be included in the Slack message. You can use the default template or you can choose to edit and customize this template to fit your organization’s specific requirements. You can also create custom templates using Go Templates.

  1. Sign in to Endor Labs and navigate to Manage>Integrations.
  2. Look for Slack under Notifications.
  3. Click Manage to view the list of configured notification integrations.
  4. Choose one and click the ellipsis on the right side, and click Edit Template.
  5. Make required changes to any of the following templates and click Save Template.
    • Open - This template is used when new notifications are raised.
    • Update - This template is used when an existing notification is updated, such as, when some findings for the notification are changed.
  6. Click Restore to Default to revert the changes.
  7. Use the download icon on the top right corner to download this template.
  8. Use the copy icon to copy the information in the template.

Data model

To create custom templates for Slack messages, you must understand the data supplied to the template.

See the protobuf specification NotificationData message used for the templates.

syntax = "proto3";

package internal.endor.ai.endor.v1;

import "google/protobuf/wrappers.proto";
import "spec/internal/endor/v1/finding.proto";
import "spec/internal/endor/v1/notification.proto";
import "spec/internal/endor/v1/package_version.proto";
import "spec/internal/endor/v1/project.proto";
import "spec/internal/endor/v1/repository_version.proto";

option go_package = "github.com/endorlabs/monorepo/src/golang/spec/internal.endor.ai/endor/v1";
option java_package = "ai.endor.internal.spec";

// The statistics for findings in a notification.
message FindingStats {
  // The total number of findings for a notification.
  google.protobuf.UInt32Value num_total_findings = 1;
  google.protobuf.UInt32Value num_total_critical_severity_findings = 2;
  google.protobuf.UInt32Value num_total_high_severity_findings = 3;
  google.protobuf.UInt32Value num_total_medium_severity_findings = 4;
  google.protobuf.UInt32Value num_total_low_severity_findings = 5;

  // The number of new findings for a notification as compared to the previous scan.
  google.protobuf.UInt32Value num_new_findings = 6;
  google.protobuf.UInt32Value num_new_critical_severity_findings = 7;
  google.protobuf.UInt32Value num_new_high_severity_findings = 8;
  google.protobuf.UInt32Value num_new_medium_severity_findings = 9;
  google.protobuf.UInt32Value num_new_low_severity_findings = 10;

  // The number of findings for a notification that was resolved in latest scan.
  google.protobuf.UInt32Value num_resolved_findings = 11;
}

// The data supplied to notification templates while rendering.
message NotificationData {
  // The raw notification object.
  Notification raw_notification = 1;

  // The name of the project.
  google.protobuf.StringValue project_name = 2;

  // The name of the violated policy that triggered the notification.
  google.protobuf.StringValue policy_name = 3;

  // The Git reference of the project that was scanned.
  google.protobuf.StringValue ref_name = 4;

  // The project URL.
  google.protobuf.StringValue project_url = 5;

  // The map of finding UUIDs to finding objects.
  map<string, internal.endor.ai.endor.v1.Finding> findings_map = 6;

  // The map of finding UUIDs to corresponding parent package version objects.
  map<string, internal.endor.ai.endor.v1.PackageVersion> package_version_map = 7;

  // The map of finding UUIDs to corresponding parent project objects.
  map<string, internal.endor.ai.endor.v1.Project> project_map = 8;

  enum NotificationType {
    NOTIFICATION_TYPE_UNSPECIFIED = 0;

    // Notification type when a notification is created.
    NOTIFICATION_TYPE_CREATE = 1;

    // Notification type when a notification is updated.
    NOTIFICATION_TYPE_UPDATE = 2;

    // Notification type when a noticiation is resolved.
    NOTIFICATION_TYPE_RESOLVED = 3;
  }

  NotificationType type = 9;

  // The project to which the notification is associated.
  internal.endor.ai.endor.v1.Project project = 10;

  // The map of finding UUIDs to the correcponding parent repository version objects.
  map<string, internal.endor.ai.endor.v1.RepositoryVersion> repository_version_map = 11;

  // The project URL in Endor Labs UI.
  google.protobuf.StringValue project_app_url = 12;

  // The policy URL in Endor Labs UI.
  google.protobuf.StringValue policy_app_url = 13;

  FindingStats finding_stats = 14;

  // The map of package version UUIDs to package version names.
  map<string, string> package_version_name_map = 15;
}

To understand Project, Finding, PackageVersion, and RepositoryVersion definitions used in this protobuf specification, see:

See the following specification to understand a few additional functions available to the template. You can access these functions by using their corresponding keys.


// FuncMap contains the additional functions that are available to notification templates.
var FuncMap = func(h *NotificationTemplate) template.FuncMap {
	return template.FuncMap{
		"now": func() string {
			now := time.Now()
			utc := now.UTC()
			return utc.Format("01-02-2006 15:04:05")
		},

		// csvFileName generates the filename for the CSV attachment for Jira.
		"csvFileName": GetJiraAttachmentFilename,

		// findingURL returns the URL for the given finding.
		"findingURL": h.getFindingURL,

		// toCSV converts the given string to a CSV format.
		"toCSV": toCSV,

		// findingLevelSlackEmoji returns the slack emoji for the given finding based on severity.
		"findingLevelSlackEmoji": GetSlackEmojiForSeverity,

		// packageName returns the user facing name of the package.
		"packageName": func(p *endorpb.PackageVersion) string {
			return lib.GetUserFacingName(p.GetMeta().GetName().GetValue())
		},

		// filteredFindingsURL returns the URL to view findings with the given uuids
		"filteredFindingsURL": common.GetFilteredFindingsURL,

		// increment increments the given integer by 1.
		"increment": func(i int) int {
			return i + 1
		},
	}
}

Run a scan

Run the endorctl scan on your configured projects. See endorctl scan commands for more information.

View notifications in Slack

View Endor Labs’ findings in Slack and take remedial actions.

  • Sign in to Slack and view the notifications on the configured channel.
  • You can view the top 3 findings by their severity level. Click View All to see all the findings in Endor Labs.

View notifications in Slack