Skip to content

feat(chat): add slack bridge with account linking and compose stack#103

Open
alexinthesky wants to merge 1 commit into
mainfrom
feat/slack-integration
Open

feat(chat): add slack bridge with account linking and compose stack#103
alexinthesky wants to merge 1 commit into
mainfrom
feat/slack-integration

Conversation

@alexinthesky

@alexinthesky alexinthesky commented Mar 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a Slack ↔ Ask O11y path: users DM the bot setup to get a one-time Grafana link (account linking), and @mention the bot in channels to run the same detached agent flow as the web UI. A Bolt + Socket Mode worker (slack-bridge/) talks to new plugin HTTP routes; docker-compose-full can run the bridge locally with automated Grafana service-account token creation.

What changed

Backend (Go plugin)

  • Slack bridge API under /api/slack-bridge/* (pending nonce, lookup, agent run + SSE) and /api/slack-link/confirm for browser confirmation, with HMAC-signed short-lived bridge tokens and shared executeDetachedAgentRun for agent execution.
  • Redis / in-memory store for pending links and Slack↔Grafana bindings (slacklink_store.go).
  • OpenAPI and tests updated for the new endpoints.
  • slackBridgeSecret read from secure JSON; compose passes SLACK_BRIDGE_SECRET into Grafana so provisioning can match the bridge.

Slack bridge (Node / Bolt)

  • New slack-bridge/ package: Socket Mode + Assistant handler for Agents UI and classic DM setup, app_mention for channel Q&A, calls to Grafana with Bearer SA token + bridge headers.
  • Dockerfile and clearer error paths (401 vs plugin/secret), token validation at startup.
  • @slack/web-api for auth.test preflight.

Frontend

  • ?slack_link= handling on Home with slackLink.ts service calling confirm API.

Dev / ops

  • scripts/server-full.sh (via npm run server:full): provisioning swap, optional npm run build, SLACK_BRIDGE_SECRET generation, compose up without slack-bridge first, SA token script + /api/user check, then --force-recreate slack-bridge.
  • scripts/create-slack-bridge-grafana-token.sh with --write-env; scripts/lib/upsert-env.sh shared upsert; scripts/verify-slack-bridge-tokens.sh.
  • npm run server:full:clean for stale Docker networks.
  • docker-compose-full.yaml: slack-bridge service; GRAFANA_TOKEN from GRAFANA_SERVICE_ACCOUNT_TOKEN or GRAFANA_TOKEN.
  • .env.example, eslint ignore for slack-bridge/node_modules, CLAUDE.md updates.

Provisioning (this branch)

  • Plugin layout under provisioning/plugins/ follows multi-org full.yaml + app.yaml_ (as used by the full stack script).

Why

  • Product: Meet users in Slack for onboarding (setup) and channel questions without duplicating agent logic client-side.
  • Reliability: Starting slack-bridge only after a valid Grafana SA token exists avoids 401 / invalid API key on /pending from an empty or stale env.
  • Operability: One-command full stack + token automation and server:full:clean reduce Docker/network friction.

Notes for reviewers

  • Slack app config (Messages tab vs Agents, scopes, events) is documented in slack-bridge/README.md.
  • Commit messages on the branch may not all pass commitlint; consider squashing with conventional messages before merge if CI enforces per-commit rules.

Note

High Risk
Adds new externally callable Slack-bridge endpoints plus HMAC/secret-based authentication and user↔Slack identity binding, which is security-sensitive and impacts how agent runs are authorized. Also introduces a new runnable service and compose/workflow automation that could break local/prod deployments if misconfigured.

Overview
Enables a new Slack bridge integration: users can DM setup to generate a one-time linking nonce and then run Ask O11y agent conversations via Slack @mentions, reusing the same detached agent execution path as the web UI.

On the backend, adds /api/slack-bridge/* and /api/slack-link/* routes (pending nonce, lookup, confirm/unlink/status, Slack-authenticated agent run + SSE) protected by a shared slackBridgeSecret, short-lived HMAC-signed X-Slack-Bridge-Token, and per-user rate limiting; includes Redis/in-memory storage for link state and updates openapi.json + tests.

Adds a new slack-bridge/ Node service (Bolt Socket Mode) with a Docker image and GHCR publishing workflow, plus updates to docker-compose-full.yaml, provisioning (slackBridgeSecret), frontend Home URL handling + slackLink service, and new helper scripts to bootstrap the full stack and manage required .env values and Grafana service-account tokens.

Written by Cursor Bugbot for commit e465baf. This will update automatically on new commits. Configure here.

@alexinthesky alexinthesky changed the title I want to add a slack integration to my plugin. what should I do to achieve this? learn all you can (vibe-kanban) feat(chat): add slack bridge with account linking and compose stack Mar 27, 2026
@alexinthesky
alexinthesky force-pushed the feat/slack-integration branch 3 times, most recently from 4acf6d6 to d9cc45f Compare March 27, 2026 16:55
Comment thread pkg/plugin/slacklink_handlers.go
Comment thread pkg/plugin/slacklink_handlers.go Outdated
Comment thread pkg/plugin/slacklink_handlers.go Outdated
Comment thread slack-bridge/src/index.ts
Comment thread docker-compose-full.yaml
Comment thread slack-bridge/src/index.ts Outdated
Comment thread pkg/plugin/slacklink_handlers.go Outdated
@alexinthesky
alexinthesky force-pushed the feat/slack-integration branch 2 times, most recently from e1db304 to 37a31e2 Compare March 31, 2026 13:52
Comment thread pkg/plugin/slacklink_handlers.go
@alexinthesky
alexinthesky force-pushed the feat/slack-integration branch from 37a31e2 to ae41f0c Compare March 31, 2026 14:08
Comment thread slack-bridge/src/index.ts Outdated
@alexinthesky
alexinthesky force-pushed the feat/slack-integration branch from ae41f0c to 4f43138 Compare April 2, 2026 09:02
Comment thread pkg/plugin/slacklink_store.go
Comment thread src/pages/Home.tsx
Comment thread pkg/plugin/slacklink_store.go

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread pkg/plugin/slacklink_handlers.go
…port

- Slack Socket Mode bridge (Node.js/Bolt) with account linking via HMAC-signed nonces
- AI assistant view: routes messages to Grafana agent loop via SSE streaming
- Account linking: email-based role mapping from Grafana, 24h stale-role warning
- Multi-org support: basic auth (GRAFANA_USERNAME/GRAFANA_PASSWORD) replaces SA token
  so a single bot works across all Grafana orgs
- RBAC: live role lookup per request; Viewers get read-only tool access
- Security: constant-time secret comparison, single-use nonces, rate limiting (20/hr)
- Session continuity: thread→session mapping with bounded LRU eviction (512 entries)
- Redis-backed link store with reverse index and stale cleanup on re-link
- docker-compose-full.yaml: adds slack-bridge service with basic auth credentials
- Home.tsx: fix orgHint race — capture before URL params are cleared
- slack-bridge userMessage: run agent for linked users, prompt unlinked to setup
- Accurate Slack app manifest (assistant_view schema) and simplified setup docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alexinthesky
alexinthesky force-pushed the feat/slack-integration branch from cebf615 to e465baf Compare April 2, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant