If your Celum deployment sits behind a firewall, use Socket Mode — it needs no inbound endpoint. See Interactivity transport below.
What gets posted
A decision made in the Celum interface and one made from a Slack button update the same channel message, so the two never disagree.
Interactivity transport
The Approve/Reject buttons need Slack to reach Celum inbound. There are two ways, and you pick one:Socket Mode
Celum opens an outbound WebSocket to Slack; clicks arrive down that tunnel. No public endpoint, no inbound firewall hole, no signing secret. Needs only egress to
slack.com:443 (via your proxy if egress is proxied — HTTP(S)_PROXY is honoured). Use this behind a firewall. Enabled by SLACK_APP_TOKEN.Request URL
Slack POSTs to
https://<host>/api/slack/interactions, authenticated by the signing secret. Requires that endpoint be internet-reachable — not an option behind a firewall. Enabled by SLACK_SIGNING_SECRET.Create the Slack app
1
Create the app
In the Slack API dashboard, choose Create New App → From scratch and pick your workspace.
2
Add bot scopes
Under OAuth & Permissions, add the Bot Token Scopes
chat:write, users:read, and users:read.email. Install the app to the workspace and copy the Bot User OAuth Token (xoxb-…).3
Invite the bot
Invite the bot to the target channel (
/invite @your-bot) and note the channel id (C0…) or its #name.4
Enable interactivity (pick one transport)
- Socket Mode (firewalled)
- Request URL (public)
- Settings → Socket Mode → toggle On. When prompted, generate an App-Level Token with the
connections:writescope and copy it (xapp-…) — this isSLACK_APP_TOKEN. (App-level tokens also live under Settings → Basic Information → App-Level Tokens.) - Features → Interactivity & Shortcuts → toggle On. With Socket Mode enabled, Slack does not ask for a Request URL.
Configure Celum
Set these on the backend. The credential values resolve from the secret store first and fall back to the environment (see Environment variables).
An empty
SLACK_BOT_TOKEN disables the integration — there is no separate enable flag; the boot log reads Slack notifications disabled. Set either SLACK_APP_TOKEN (Socket Mode — boot logs socket mode enabled) or SLACK_SIGNING_SECRET (Request URL). Behind a firewall, use Socket Mode.
Approving from Slack
A button click carries no Celum session — Slack has no cookie. Trust comes from the transport itself: the app-level token on the Socket Mode connection, or the Slack request signature on the Request URL callback (verified withSLACK_SIGNING_SECRET, within a five-minute window to block replays). The clicker is then authorized like any other approver:
- their Slack account is resolved to an email (hence the
users:read.emailscope), - their groups are read from their last Celum login (cached when they sign in),
- the same
cluster:ApproveDeletecheck and the two-person rule apply — a requester can never approve their own deletion.
Cluster health notifications
A background watcher reads the shared cluster-health cache and posts only on transitions — reachable → unreachable and back — so a steady state is silent and a backend restart never floods the channel (the first reading of each cluster seeds state without posting). Clusters that are mid-provision or mid-deletion (health unknown) are skipped until they report a definite state. The watcher runs only when Slack is enabled.Security notes
- Socket Mode adds no inbound surface — the connection is dialled out from Celum and authenticated by the app-level token, so nothing needs to be exposed. This is why it’s the right choice behind a firewall.
- Request URL mode’s
/api/slack/interactionsis a public, internet-reachable route — Slack must be able to POST to it. It bypasses session auth and route-level IAM by design and is protected solely by signature verification. Don’t expose it on firewalled deployments — use Socket Mode instead. - The bot token, app-level token, and signing secret are credentials: keep them in the secret store (
backend/slack) in production rather than in a plain.env.