Slack, Teams & Discord
Route findings and events into your team's Slack workspace, Microsoft Teams tenant, or Discord server — set up credentials, pick a default channel, and understand what's two-way today.
Slack, Teams & Discord
Safeguard can push findings and platform events directly into a team's existing chat tool — a Slack workspace, a Microsoft Teams tenant, or a Discord server — so security signal shows up where people already work instead of requiring them to log in and go looking for it. These are dedicated ChatOps integrations, each with its own connection setup, credential validation step, and default-channel routing; they're available across Safeguard's ESCM, Portal, and TPRM products under Settings → Integrations. (Per-event channel routing exists in the data model but not the UI yet — see Channel mapping and routing below.)
This is a materially richer feature than a single "OAuth evidence source" line — if you're looking for the flat list of all 394 connectors Safeguard can pull compliance evidence from (which also lists Slack, Teams, and Discord as generic OAuth sources), see Connectors instead. This page covers the actual notification/ChatOps feature: its setup flow, its channel-routing model, and — most importantly — how much of it is genuinely two-way today.
Which platform should I use?
| Platform | Auth options | Channel routing today | Inbound commands |
|---|---|---|---|
| Slack | Bot Token or Incoming Webhook | One default channel, set during setup. Per-event mapping (with @mention support) exists in the data model but has no UI control yet | Supported at the data-model level (no self-service UI yet) |
| Microsoft Teams | Incoming Webhook or Bot Framework | One default team + channel, set during setup. Per-event mapping exists in the data model but has no UI control yet | Not supported — notification-only |
| Discord | Bot Token or Webhook | One default channel, set during setup. Per-event mapping exists in the data model but has no UI control yet | Supported at the data-model level (no self-service UI yet) |
All three are configured the same general way: pick an authentication type, enter its credentials, let Safeguard validate them and pull your channel (or team/server) list, then pick where the default notifications go. Details differ per platform below.
Setting up Slack
-
In Safeguard, go to Settings → Integrations and click Connect on the Slack tile.
-
On the Credentials step, fill in:
Field Required Notes Integration Name Yes Must be unique across your integrations Description No Authentication Type Yes BOT_TOKENorINCOMING_WEBHOOKBot Token Only for BOT_TOKENA Slack app's bot token ( xoxb-...), from OAuth & Permissions in your Slack appWebhook URL Only for INCOMING_WEBHOOKA Slack Incoming Webhook URL ( https://hooks.slack.com/services/...) -
Click Next. Safeguard validates the credentials first — for
BOT_TOKEN, a successful validation also fetches your workspace's channel list;INCOMING_WEBHOOKcredentials validate but skip channel listing, since a webhook is already bound to one channel. -
On the Channel step:
- Bot Token: pick a Default Channel from the list Safeguard just fetched. If no channels appear, the bot hasn't been invited to any channel yet — see Troubleshooting.
- Incoming Webhook: there's nothing to pick — messages go to whatever channel the webhook URL is bound to. You can optionally type in a display name for that channel.
Auth type comparison: BOT_TOKEN ("Bot Token (Full Access)" in the UI) gives Safeguard a channel picker across your workspace, so you can choose which channel gets notifications. INCOMING_WEBHOOK ("Incoming Webhook (Send Only)") is faster to set up but only ever posts to the one channel the webhook was created for.
Slack's configuration model also has
signingSecretandappTokenfields, and aslashCommandEnabledflag — none of these are exposed in the Settings connection flow today. See Bidirectional input below.
Setting up Microsoft Teams
-
Go to Settings → Integrations and click Connect on the Teams tile.
-
On the Credentials step, fill in:
Field Required Notes Integration Name Yes Must be unique across your integrations Description No Authentication Type Yes WEBHOOKorBOT_FRAMEWORKWebhook URL Only for WEBHOOKAn Incoming Webhook connector URL created in a Teams channel ( https://outlook.office.com/webhook/...)Microsoft Tenant ID Only for BOT_FRAMEWORKYour Azure/Entra tenant GUID App ID (Client ID) Only for BOT_FRAMEWORKThe registered app's client ID App Secret (Client Secret) Only for BOT_FRAMEWORKThe registered app's client secret All three Bot Framework fields are required together — Safeguard won't let you proceed with only some of them filled in.
-
Click Next. Credentials are validated first; for
BOT_FRAMEWORK, a successful validation also fetches the Microsoft Teams teams your app can see.WEBHOOKcredentials validate but there's no team/channel list to fetch, since the webhook already targets one channel. -
On the Channel step:
- Bot Framework: pick a Team, then pick a Channel within that team — Teams' hierarchy is team-then-channel, not a flat channel list like Slack or Discord.
- Webhook: nothing to pick; you can optionally type in a display name for the target channel.
Auth type comparison: WEBHOOK ("Incoming Webhook (Send Only)") is the fastest path and posts to a single, pre-bound channel. BOT_FRAMEWORK ("Bot Framework (Full Access)") requires registering an Azure AD app and grants Safeguard visibility into your teams and channels, so you can pick which team and channel gets the default notifications.
Microsoft Teams' configuration model also includes a notificationTypes field (a list of notification-type strings), which — like the fields noted for Slack — is present in the API model but not currently exposed as a control in the Settings connection flow.
Setting up Discord
-
Go to Settings → Integrations and click Connect on the Discord tile.
-
On the Credentials step, fill in:
Field Required Notes Integration Name Yes Must be unique across your integrations Description No Authentication Type Yes BOT_TOKENorWEBHOOKBot Token Only for BOT_TOKENFrom the Bot section of a Discord application in the Discord Developer Portal Webhook URL Only for WEBHOOKA Discord channel webhook URL ( https://discord.com/api/webhooks/...) -
Click Next. Credentials are validated first — for
BOT_TOKEN, a successful validation also fetches the list of Discord servers (guilds) the bot has been added to. ForWEBHOOK, the validation response returns the webhook's own channel directly, since a Discord webhook is scoped to a single channel. -
On the Server & Channel step:
- Bot Token: pick a Server, then pick a Channel in that server — Safeguard filters the channel list down to text channels only.
- Webhook: nothing to pick; you can optionally type in a display name for the channel.
Auth type comparison: BOT_TOKEN ("Bot Token (Full Access)") gives Safeguard a server/channel picker across every Discord server the bot has joined. WEBHOOK ("Webhook URL (Send Only)") is quicker but limited to the one channel the webhook is bound to.
Like Slack, Discord's configuration model includes a
slashCommandEnabledflag that isn't exposed in the connection drawer today — see the next section.
Credential validation, every time
For all three platforms, Safeguard validates credentials in a dedicated step before it ever tries to list channels, teams, or servers — you can't get to a channel picker with credentials Safeguard hasn't already confirmed work. If validation fails (revoked token, wrong scopes, malformed webhook URL, wrong tenant), you get an inline error and the flow doesn't advance. This is the same underlying step whether you're creating a new integration or editing an existing one with new credentials.
Channel mapping and routing
This section describes a data model, not a shipped feature. All three platforms' configuration objects (
SlackConfiguration,TeamsConfiguration,DiscordConfiguration) carry achannelMappingsarray meant to route specific event types to specific channels instead of sending everything to one default channel. We checked all three connection drawers directly: none of them expose any UI to create, view, or edit a channel mapping. Every integration you set up today — on any of the three platforms — sends everything to the single default channel (or team + channel, for Teams) you picked in step 2 of setup. A freshly created integration'schannelMappingscomes back as an empty array, and there is no self-service way to populate it.
If and when per-event routing ships, the mapping shape is not identical across platforms — don't assume feature parity:
| Field | Slack | Teams | Discord |
|---|---|---|---|
eventType | Yes | Yes | Yes |
Target channel (channelId / channelName) | Yes | Yes (plus teamId / teamName, since Teams channels live inside a team) | Yes |
messageTemplate | Yes | Yes | Yes |
mentionUsers / mentionGroups (@-mention on match) | Yes — Slack only | No | No |
minSeverity (minimum severity threshold) | Yes | Yes | Yes |
isEnabled (per-mapping on/off) | Yes | Yes | Yes |
description | Yes | Yes | Yes |
Concretely:
- Slack is the only platform whose mapping type carries
mentionUsersandmentionGroups— a mapping could @-mention a person or group when it fires, on top of a custommessageTemplate, once this is exposed. - Teams mappings are scoped by both
teamId/teamNameandchannelId/channelName, reflecting that Teams channels are nested inside a team rather than existing in a flat list. - Discord mappings look structurally like Slack's minus the mention fields —
eventType, channel, template, severity threshold, enabled flag, description.
The intent is clear from the shape: minSeverity would let you route, say, only critical/high findings to a paged-on-call channel while lower-severity events go somewhere quieter, and isEnabled would let you silence a specific mapping without deleting it. None of that is usable yet — today, severity filtering and per-event routing happen upstream, if at all, via webhook filters rather than through a chat-integration setting.
Example: what Safeguard stores after setup
Completing the Slack drawer with BOT_TOKEN auth produces a SlackConfiguration that looks like this (real field names, illustrative values):
{
"id": 42,
"integrationName": "Security Alerts – Slack",
"authType": "BOT_TOKEN",
"workspaceName": "acme-corp",
"botUserName": "safeguard-bot",
"defaultChannelId": "C0123ABCDE",
"defaultChannelName": "security-alerts",
"webhookEnabled": false,
"slashCommandEnabled": false,
"channelMappings": [],
"isActive": true
}channelMappings is [] here — and will stay [] for every integration created through Settings today, since there's no drawer step, button, or form field anywhere in the product that writes to it.
Bidirectional input (slash commands)
This is the most important thing to understand about maturity here, so we'll be precise rather than aspirational.
What's confirmed in the data model: both the Slack and Discord configuration types (SlackConfiguration / CreateSlackConfigurationRequest and DiscordConfiguration / CreateDiscordConfigurationRequest) include a slashCommandEnabled field. That means Safeguard's integration data model is built to support inbound interaction — a user typing a command or query back into Safeguard from within a Slack or Discord conversation — not just one-way outbound notifications.
What's actually in the setup UI today: neither the Slack nor the Discord connection drawer (the Settings screens described above) expose a toggle, checkbox, or any control for slashCommandEnabled. We checked both directly — there is no self-service way to turn this on from Settings right now. Treat inbound slash commands as a capability the platform is architected to support, not a feature you can enable today.
Microsoft Teams is notification-only. The Microsoft Bot Framework is, generically, a real two-way bot protocol in the Microsoft ecosystem — but there is no equivalent field anywhere on TeamsConfiguration or CreateTeamsConfigurationRequest. Safeguard's Teams integration has no inbound-command capability today, at either the UI or data-model level; describe it as send-only.
If inbound commands matter to your workflow now, ask your Safeguard account team whether slash-command support has moved from the data model into general availability — the field being present doesn't guarantee a shipped, supported command surface yet.
FAQ & Troubleshooting
Credential validation fails immediately.
Double-check you're using the right credential for the auth type you selected — a Slack bot token (xoxb-...) won't validate under INCOMING_WEBHOOK, and vice versa. For Teams BOT_FRAMEWORK, all three of Tenant ID, App ID, and App Secret must be correct together; a single wrong value fails validation with no partial credit.
No channels show up in the Slack or Discord channel picker.
This is the single most common setup snag with bot-based (not webhook-based) chat integrations: the bot has valid credentials, but it hasn't actually been added to any channel or server yet. In Slack, invite the bot to at least one channel (/invite @your-bot-name in that channel) and retry — Safeguard's own UI message here is literally "No channels found. Make sure the bot is invited to at least one channel." In Discord, make sure the bot has actually been added to a server (guild) via its OAuth invite link, with permission to view the channels you expect to route to — note that Discord's picker doesn't show an equivalent "no servers found" message; if your bot has no servers, the Select Server step just sits on "Loading servers..." indefinitely rather than telling you to invite the bot, so don't assume it's still working if it hasn't resolved after a few seconds.
Teams shows no teams, or no channels within a team. Confirm the Azure AD app tied to your App ID/App Secret has actually been granted access to the tenant and to the specific teams you expect to see — an app that validates successfully can still have zero visibility into teams it hasn't been added to.
Should I use a webhook or a bot/app integration? Webhooks (Slack Incoming Webhook, Teams Incoming Webhook, Discord Webhook) are the fastest to set up and are fine if you only ever want notifications in one fixed channel. Bot-based integrations (Slack Bot Token, Teams Bot Framework, Discord Bot Token) take a bit more setup but unlock a channel/team picker, so you can choose which single channel gets the default notifications instead of being stuck with whatever channel a webhook was created against. Neither path gets you per-event routing today — see Channel mapping and routing above.
How is this different from the Slack/Teams/Discord entries on the Connectors page? The Connectors page catalogs these three as generic OAuth evidence sources alongside 391 other systems Safeguard can pull compliance evidence from — it's a different, much shallower integration path. The ChatOps integrations on this page are dedicated notification features with their own setup drawer, credential validation, a default-channel picker, and (for Slack/Discord) an inbound-command data model — richer than a generic connector, even though per-event channel mapping isn't wired up to the UI yet either.
Why can't I route different event types to different channels, or set a minimum severity per channel?
Because there's no UI for it yet. The channelMappings data model (see above) is designed for exactly this — per-event routing, minSeverity thresholds, Slack @-mentions — but none of the three connection drawers expose a way to create a mapping, so every integration sends everything to its single default channel regardless of event type or severity. If this is a blocker, ask your Safeguard account team whether it's on a near-term roadmap.
I'm editing an existing integration and it's not asking me to re-enter credentials. That's expected, not a bug: if you leave the Bot Token / Webhook URL / App Secret fields blank while editing and don't change the authentication type, Safeguard reuses the credentials already on file and skips re-validation for that step. Only fill in a credential field if you're actually rotating it.
Related
- Connectors — the broader connector catalog, including Slack/Teams/Discord as generic OAuth evidence sources.
- Integrations — the full integrations index across SCM, registries, ticketing, and more.
- Webhooks & Events — the event catalog that channel-mapping
eventTypevalues route from; useful if you're deciding which events deserve their own channel. - Guardrails & Enforcement — Safeguard's policy-as-code severity gating, conceptually similar to a channel mapping's
minSeveritythreshold but enforced in your pipeline rather than routed to chat.