Connect Slack to Cortex
Capture channel messages with bot and app-level tokens.
Slack
Content and access
Captured public-channel content is available to organization-wide Search. Direct messages and private-channel messages are excluded from that Search scope.
Set up Slack
An admin connects this app for the Cortex organization. Grant access only to content appropriate for the whole organization.
What you need: permission to create and install a Slack app in the workspace.
Stage 1: configure the Slack app in Slack
Create a Slack app for the workspace. Under OAuth & Permissions, add these Bot Token Scopes:
channels:history
channels:read
groups:read
im:read
mpim:read
users:read
users:read.emailAll seven scopes are required. Cortex does not read direct messages, but Slack requires im:read and mpim:read for the channel-list request; omitting either produces an empty list.
Slack's live message search API accepts a user token only. Add these User Token Scopes if your deployment uses live Slack message search:
search:read
users:read.emailThen finish the Slack app:
- Enable Socket Mode.
- Enable Event Subscriptions and subscribe to the
message.channelsandmessage.groupsbot events. - Create an app-level token with the
connections:writescope. - Install the app to the workspace. If you change scopes after installing, reinstall it.
- Copy the bot token (
xoxb-…), the app-level token (xapp-…), and the user token (xoxp-…) if you configured one.
Stage 2: connect Slack to Cortex
- In Cortex, open Organization → Apps and add Slack.
- Enter the bot token in Bot token and the app-level token in App-level token (optional). Add the search user token under Search user token (optional) if you created one.
- Select Test & preview and confirm the expected Slack workspace.
- Select Configure channels, review the channels Cortex found, and turn ingest off for any it should not use.
xoxb-…) and App-level token (optional) (xapp-…) together. Despite its label, the app-level token is required for this Socket Mode connection. Without it, verification expects a search-only user token (xoxp-…) in the first field and rejects a bot token.The search user token is optional and supports live Slack message search. Organization-wide Cortex Search reads captured public-channel content, so channel capture and those Search results work with the bot and app-level tokens.
What Search returns
Organization-wide Search returns public-channel content. Direct messages and private-channel messages are not shown in organization-wide Search.
In Slack channels, ingest state is on each row. Turning ingest off hides that channel from Search and Ask.
Technical details
Cortex reaches Slack only through outbound connections: Web API calls and a Socket Mode WebSocket to slack.com, plus Slack's CDN (slack-edge.com) only when an admin imports profile photos. Cortex has no Slack request URL, so Slack never calls into Cortex.
Authentication
- On save, Cortex calls
auth.testwith the token, reads the granted scopes from Slack'sx-oauth-scopesresponse header, and rejects the token if any required scope is missing. It keeps the verified workspace ID, name and URL, the bot's user name, and the granted scope list. - Tokens are encrypted at rest with a Cortex-held key before they are written to Cortex's Postgres database. The API returns only which token names are stored, never their values, which is why the UI shows Stored.
- Each token has one job. The bot token lists channels and reads channel history and the user directory (
users.list,users.lookupByEmail,users.info). The app-level token only opens the Socket Mode connection. The optional user token is used only for Slack'ssearch.messages.
What Cortex reads
- Channel scope. On connect, Cortex lists channels with
conversations.list, registers every channel the bot can see, and joins every public channel itself. Ingest is on by default; an admin turns individual channels off, or removes them, in Configure channels. Slack does not let a bot join a private channel; if a member invites the bot, that channel is captured too, but its messages stay out of organization-wide Search. - Live events. With the app-level token, the Cortex Slack listener opens the Socket Mode connection and receives
messageevents (new, edited, deleted) for channels the bot is in. Events from direct messages and group direct messages are discarded before they are queued.im:readandmpim:readare required only because Slack's channel-list call fails without them; those conversations are never read. - Content. The listener then fetches the full thread with the bot token through
conversations.repliesandconversations.history. When a channel is first registered, Cortex backfills up to the newest 3,000 messages, then follows new activity; a periodic reconciliation sweep fills gaps. - Directory.
users.listandusers.lookupByEmailmap Slack user IDs to Cortex people by work email. An admin can also import profile photos from Slack.
Cortex does not download message files or attachments; file names and link previews that arrive inside a message payload are stored with it. The only binary content Cortex fetches is profile photos, when an admin runs the import. Cortex does not read direct messages.
Where data is stored
Messages are written to Cortex's Postgres database, in tables keyed by your Cortex organization ID: channel ID, message timestamp, thread timestamp, Slack user ID, message text, the message payload as received, and a permalink when one appears in a linked pull request. Thread rollups (participants, counts, last activity) and per-channel settings sit beside them. An edit in Slack updates the stored row; when Slack delivers a deletion event, the message is marked deleted and leaves Search. Search runs over this stored copy with Postgres full-text search, and a channel is searchable only while Cortex has recent proof from Slack that it is public. Retrieval indexes for Search and Ask are built from these stored rows and kept in the same database; model calls run through Cortex's model gateway under the providers agreed for your deployment. Connection changes are written to the audit log.
Revoke and delete
Turning ingest off for a channel hides it from Search and Ask and keeps its stored messages. Remove on a channel marks its stored messages deleted so they are not served again. Revoke or Delete on the connection closes the Socket Mode connection within a minute, stops token use and Search for that workspace, and is written to the audit log. Neither uninstalls the Slack app: remove it under your workspace's Manage apps. Messages already captured stay under your organization's retention terms until removed per channel or purged by Chaos Labs.
Manage this connection
After changing permissions in Slack, return to Organization → Apps and run Test & preview. A preview is a limited sample of accessible content.
See the shared connection management guide for credential updates, reauthorization, and revocation. The complete Slack procedure is also available in Workplace connections.