What the OAuth connection supports
- Helpful and unhelpful answer ratings, including bounded reviewer context.
- A signed Suggest correction modal that records scrubbed unhelpful feedback and creates an Owner/Admin-approved Knowledge draft; it never auto-publishes.
- A signed Translate modal that privately translates the review on demand for the mapped reviewer while preserving the original question and answer.
- New or recurring Inbox issues, with Resolve and Snooze actions.
- Governed-action approval requests, with Approve and Deny actions.
- A queued test plus delivery health, provider error codes, and last successful test/delivery timestamps.
chat.postEphemeral to the mapped reviewer. There is no
public-message fallback; ambiguous delivery is never automatically resent.
Connect a workspace
- Open Integrations → Slack and choose Connect with Slack.
- Review the requested
chat:writeandincoming-webhookscopes. - Select the Slack workspace and channel, then finish authorization.
- Map each allowed Slack member ID to a current Puntego member.
- Select event families, save, and queue a test.
Security and delivery contract
- OAuth state is single-use, expires after ten minutes, and is bound to the exact Puntego tenant, user, and dashboard session. Authorization codes are exchanged once and are never stored or retried after an ambiguous failure.
- Bot tokens and Incoming Webhook URLs are stored as tenant-bound ciphertext; only non-secret workspace, channel, health, and URL-hint metadata is returned.
- Slack requests are verified against the raw request body with the signing secret, a constant-time HMAC comparison, and a five-minute timestamp window.
- Button values are independently signed, tenant/team/integration/resource bound, short-lived, and size limited. The API acknowledges valid clicks quickly; mutations run later from a durable, idempotent, lease-fenced job.
- Correction and translation modals carry separately signed private metadata bound to the callback, app, team, reviewer, channel, message, resource, and a ten-minute expiry. Exact callback and block/action IDs are required.
- Membership and role are checked again during execution. A replay, expired approval, already-decided approval, or revoked reviewer cannot run an action twice.
- Outbound event delivery uses a tenant-scoped durable outbox. Slack
429responses honorRetry-After; an ambiguous network failure after dispatch begins is retained asunknown_delivery_stateinstead of risking a duplicate. - After a decision, Puntego replaces the original button row with the bounded result so a finished review no longer looks actionable. If Slack rejects that edit, Puntego falls back to a thread reply. This notification remains best-effort after the authoritative Puntego mutation; the dashboard is the source of truth if Slack cannot receive either update.
- Terminal interaction jobs are purged after 90 days. Customer erasure scrubs attributable correction text, locale, resource linkage, and receipt IDs.
Slack app configuration
The hosted environment must configure all five values before OAuth and interactivity become available:SLACK_APP_IDSLACK_CLIENT_IDSLACK_CLIENT_SECRETSLACK_SIGNING_SECRETSLACK_OAUTH_REDIRECT_URI
POST /api/slack/interactions, enable Incoming Webhooks, and grant only
chat:write,incoming-webhook. Puntego fails closed if the returned app ID,
team, channel, bot token, or exact granted-scope set does not match the install
contract.
Advanced: manual Incoming Webhook
Manual mode accepts only an HTTPShooks.slack.com or hooks.slack-gov.com
Incoming Webhook URL with Slack’s exact path shape. It can deliver selected
events and health diagnostics, but it cannot authenticate reviewers or process
buttons. Saving a manual URL deliberately switches the workspace to this
outbound-only mode.
See Slack’s official documentation for OAuth
installation,
request verification,
interactive request handling,
chat.update, and
chat.postEphemeral.