> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endorlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.endorlabs.com/feedback

```json
{
  "path": "/integrations/slack/index",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Set up Slack integration

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

export const CodeFile = ({src, lang, expandable = true, maxLines = 15}) => {
  const [content, setContent] = useState(null);
  const [wrapperLang, setWrapperLang] = useState('text');
  const [error, setError] = useState('');
  const [copied, setCopied] = useState(false);
  const [isDark, setIsDark] = useState(false);
  const [expanded, setExpanded] = useState(false);
  useEffect(() => {
    const root = document.documentElement;
    setIsDark(root.classList.contains('dark'));
    const observer = new MutationObserver(() => {
      setIsDark(root.classList.contains('dark'));
    });
    observer.observe(root, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => {
      observer.disconnect();
    };
  }, []);
  useEffect(() => {
    if (!src) {
      setError('No src provided.');
      return undefined;
    }
    const ac = new AbortController();
    fetch(src, {
      signal: ac.signal
    }).then(r => {
      if (!r.ok) throw new Error(r.status + ' ' + r.statusText);
      return r.json();
    }).then(data => {
      setContent(data.content || '');
      if (data.lang) setWrapperLang(data.lang);
    }).catch(err => {
      if (err.name !== 'AbortError') {
        setError('Unable to load ' + src + ': ' + err.message);
      }
    });
    return () => {
      ac.abort();
    };
  }, [src]);
  const language = lang || wrapperLang || 'text';
  const handleCopy = () => {
    if (!content) return;
    navigator.clipboard.writeText(content).then(() => {
      setCopied(true);
      setTimeout(() => {
        setCopied(false);
      }, 2000);
    }).catch(() => {});
  };
  const toggleExpand = () => {
    setExpanded(v => !v);
  };
  const statusBoxStyle = variant => {
    const base = {
      padding: '12px 16px',
      borderRadius: '6px',
      fontSize: '14px'
    };
    if (variant === 'error') {
      return {
        ...base,
        background: isDark ? '#451a1a' : '#fef2f2',
        color: isDark ? '#fca5a5' : '#dc2626',
        border: '1px solid ' + (isDark ? '#7f1d1d' : '#fecaca')
      };
    }
    return {
      ...base,
      background: isDark ? '#1f2937' : '#f5f5f5',
      color: isDark ? '#9ca3af' : '#6b7280'
    };
  };
  const shellStyle = {
    position: 'relative',
    borderRadius: '8px',
    border: '1px solid ' + (isDark ? 'rgba(255,255,255,0.1)' : '#d1d5db'),
    overflow: 'hidden'
  };
  const copyBtnStyle = {
    position: 'absolute',
    top: '8px',
    right: '8px',
    padding: '4px 8px',
    fontSize: '12px',
    lineHeight: '1',
    border: '1px solid rgba(255,255,255,0.3)',
    borderRadius: '4px',
    background: 'rgba(255,255,255,0.15)',
    color: '#fff',
    cursor: 'pointer',
    zIndex: 2,
    transition: 'background 0.15s, color 0.15s'
  };
  const renderErrorBox = () => <div style={statusBoxStyle('error')}>{error}</div>;
  const renderLoadingBox = () => <div style={statusBoxStyle('loading')}>Loading…</div>;
  const countLogicalLines = text => {
    const normalized = text.replace(/\n+$/, '');
    if (normalized === '') {
      return 0;
    }
    return normalized.split('\n').length;
  };
  const lineCount = content ? countLogicalLines(content) : 0;
  const showTruncate = expandable && lineCount >= maxLines && !expanded;
  const showExpandToggle = expandable && lineCount >= maxLines;
  const LINE_HEIGHT_PX = 25;
  const previewMaxHeightPx = maxLines * LINE_HEIGHT_PX;
  const preStyle = {
    margin: 0,
    padding: '16px',
    overflow: 'auto',
    maxHeight: showTruncate ? previewMaxHeightPx + 'px' : 'none',
    overflowY: showTruncate ? 'hidden' : 'auto'
  };
  const toggleLinkStyle = {
    display: 'block',
    width: '100%',
    boxSizing: 'border-box',
    background: 'none',
    border: 'none',
    padding: '8px 16px 12px 16px',
    cursor: 'pointer',
    color: '#26D07C',
    fontSize: '13px',
    fontFamily: 'inherit',
    textAlign: 'left'
  };
  const renderLoaded = () => <div style={shellStyle}>
      <button type="button" onClick={handleCopy} aria-label="Copy code" style={copyBtnStyle} onMouseEnter={e => {
    e.currentTarget.style.background = 'rgba(255,255,255,0.25)';
  }} onMouseLeave={e => {
    e.currentTarget.style.background = 'rgba(255,255,255,0.15)';
  }}>
        {copied ? 'Copied!' : 'Copy'}
      </button>
      <pre style={preStyle}>
        <code className={'language-' + language} style={{
    fontSize: '14px'
  }}>
          {content}
        </code>
      </pre>
      {showExpandToggle ? <button type="button" style={toggleLinkStyle} onClick={toggleExpand} aria-expanded={expanded ? 'true' : 'false'} aria-label={expanded ? 'Show less code' : 'See all ' + lineCount + ' lines of code'}>
          {expanded ? '... Show less' : '... See all ' + lineCount + ' lines'}
        </button> : null}
    </div>;
  if (error) {
    return renderErrorBox();
  }
  if (content === null) {
    return renderLoadingBox();
  }
  return renderLoaded();
};

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-incoming-webhooks-in-slack)
* [Configure Slack integration](#configure-slack-integration)
  * [Associate an action policy with a Slack notification](#associate-an-action-policy-with-a-slack-notification)
  * [Manage Slack notification targets in Endor Labs](#manage-slack-notification-targets-in-endor-labs)
  * [Customize Slack notification templates](#customize-slack-notification-templates)
  * [Data model](#data-model)
* [Run a scan](#run-a-scan)
  * [View notifications in Slack](#view-notifications-in-slack)

## 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.

<Note>
  We recommend you designate a channel in your Slack workspace for receiving Endor Labs notifications and create an incoming webhook for that channel.
</Note>

To create incoming webhooks in Slack:

1. Create a [Slack app](https://api.slack.com/apps?new_app=1) 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](https://api.slack.com/apps?new_app=1).
   * 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](https://api.slack.com/messaging/webhooks)

## 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 a scan matches policy conditions. 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 **None (Notify for each Finding)** to trigger a separate message for each finding.
  * Choose **Project** to group and send all the findings related to a project in one message.
  * Choose **Dependency** to send individual messages for every dependency.
  * Choose **Dependency per package version** to send individual messages for every unique combination of dependency and package version.

  You can see the top three findings from the highest available severity level. If fewer than three findings exist, only those appear.

* From **Assign Scope**, include the project tags in **INCLUSIONS** to apply this policy to a project.

See [Create an action policy](/platform-administration/policies/action-policies) 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 for 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](https://pkg.go.dev/text/template).

1. Sign in to Endor Labs and select **Integrations** from the left sidebar.
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 applies when Endor Labs raises new notifications.
   * **Update** - This template applies when an existing notification updates, such as when findings change.
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.

<CodeFile src="/templates/notifications/notification_data.json" lang="proto" />

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

* [Project resource kind](/developers-api/rest-api/using-the-rest-api/data-model/resource-kinds#project)
* [Finding resource kind](/developers-api/rest-api/using-the-rest-api/data-model/resource-kinds#finding)
* [PackageVersion resource kind](/developers-api/rest-api/using-the-rest-api/data-model/resource-kinds#packageversion)
* [RepositoryVersion resource kind](/developers-api/rest-api/using-the-rest-api/data-model/resource-kinds#repositoryversion)

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

<CodeFile src="/templates/notifications/notification_func_map.json" lang="go" />

## Run a scan

Run the endorctl scan on your configured projects. See [endorctl scan commands](/developers-api/cli/commands/scan) 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.

<img src="https://mintcdn.com/endorlabs-b4795f4f/dHzwUrp_QbpzV9uv/images/integrations/slack/slack_notifications.webp?fit=max&auto=format&n=dHzwUrp_QbpzV9uv&q=85&s=046954c16dbfa7d988c3ca9e975300c7" alt="View notifications in Slack" width="1992" height="1358" data-path="images/integrations/slack/slack_notifications.webp" />
