# Slack integration

> Approve and reject query requests from Slack with interactive buttons, verified end-to-end with HMAC-SHA256 signatures.

- Documentation: Guides
- Updated: 2026-09-07
- Source: https://queryproxy.com/docs/slack-integration/
- Language: en-US
- Author: Muhammet ŞAFAK

---
With the Slack integration, new query requests are announced in a channel with
**Approve / Reject** buttons, and decisions flow back into QueryProxy — with the
same rules as the web (role checks, no self-approval), cryptographically
verified.

## Setup

1. **Create a Slack app** for your workspace at
   [api.slack.com/apps](https://api.slack.com/apps).
2. Enable **Incoming Webhooks** and add a webhook for your approvals channel
   (e.g. `#db-approvals`).
3. Enable **Interactivity** and set the request URL to:

   ```
   https://your-queryproxy-host/webhooks/slack/interactions
   ```

4. In QueryProxy, open **ChatOps** (as DBA) and paste the **webhook URL** and
   the app's **signing secret**. Both are stored encrypted.
5. In **Admin → Users**, fill each reviewer's **Slack member ID** (e.g.
   `U0123ABC` — visible in a Slack profile under *Copy member ID*). This maps
   Slack clicks to QueryProxy users.

## What it looks like

When a request is submitted, QueryProxy posts a message with the requester,
the connection, a SQL preview and three actions: **Approve**, **Reject** and
**Open in QueryProxy**. After a decision the message is updated in place —
buttons disappear and the outcome is shown, so a request can't be decided twice
from a stale message.

Rejections from Slack record the generic reason "Rejected via Slack by
&lt;name&gt;". For a written justification, reject from the web UI.

## Security

Every callback from Slack is verified before anything happens:

- **Signature** — the `X-Slack-Signature` header must match
  `v0=HMAC_SHA256("v0:{timestamp}:{raw_body}", signing_secret)`, compared in
  constant time.
- **Replay protection** — requests older than **±5 minutes** (per
  `X-Slack-Request-Timestamp`) are rejected.
- **Identity** — the clicking Slack user must be mapped to a QueryProxy user
  with the DBA role in the request's team. Unmapped or unauthorized users get a
  private error message and nothing changes.
- **Rules** — self-approval is blocked in Slack exactly as on the web.

A forged or stale callback returns `401` and changes no state. The webhook
endpoint is also rate-limited.
