Draft: PoC (do not merge): one GitLab Duo group per Slack workspace

Proof of concept. Do not review or merge. Throwaway code to explore the experience proposed in gitlab-org#23704 (comment 4003608381) (video and discussion there). We'll rebuild it properly once we agree on the direction.

What it does

  • One GitLab Duo group per Slack workspace. All Slack sessions from a workspace run and bill in that group, instead of each user's default Duo namespace.
  • Installing the app on a top-level group makes it the Duo group, and turns on the Slack flow there.
  • Reworked Slack integration page, following Nick's design: cards for Slack workspace, GitLab Duo, Notifications (list with "+") and Slash commands. Every read-only state says who can change it.
  • Marketplace picker (/-/profile/slack/edit): top-level groups first.
  • Self-managed: the admin picks the Duo group in the Admin area.

Try it in your GDK (about 5 minutes, no Slack app needed)

The seed script creates test users, groups and fake Slack workspaces for every state, so you can click through without a Slack app.

cd gitlab
git fetch origin && git checkout duo/feature/slack-duo-group-poc
bin/rails db:migrate                              # adds one table: slack_workspace_duo_groups
bin/rails runner scripts/slack_duo_poc/seed.rb    # prints the table below
gdk restart rails-web

Password for every user: Sl4ck-Duo-Poc-2026!

Sign in as Open You see
slack-newbie /-/profile/slack/edit Marketplace picker, groups first
slack-newbie /groups/empty-co/-/settings/integrations/gitlab_slack_application/edit Nothing installed yet
slack-maintainer /fresh-co/web/-/settings/integrations/gitlab_slack_application/edit A Maintainer installed Slack on a project. Duo is off: "ask an Owner"
slack-newbie /groups/fresh-co/-/settings/integrations/gitlab_slack_application/edit The Owner turns Duo on without a group install
slack-newbie /groups/duo-co/-/settings/integrations/gitlab_slack_application/edit Duo on and Ready
slack-maintainer /duo-co/web/-/settings/integrations/gitlab_slack_application/edit Read-only Duo, notifications inherited from the group
slack-other /groups/other-co/-/settings/integrations/gitlab_slack_application/edit "Managed in another group"
slack-newbie /groups/acme-corp/-/settings/integrations/gitlab_slack_application/edit Instance-wide install: the admin decides (self-managed mode only)
slack-admin /admin/application_settings/integrations/gitlab_slack_application/edit The admin picks the Duo group (self-managed mode only)

Moments you can trigger:

bin/rails runner scripts/slack_duo_poc/seed.rb break     # someone turns off the Slack flow in Duo Co -> reload, click Fix
bin/rails runner scripts/slack_duo_poc/seed.rb install   # simulates "Add to Slack" on Empty Co -> Duo turns on by itself
bin/rails runner scripts/slack_duo_poc/seed.rb           # back to the start state, any time

GitLab.com mode (optional)

GitLab.com has no instance-wide integrations, so the last two rows of the table only work in self-managed mode. To see the GitLab.com behaviour:

echo 'export GITLAB_SIMULATE_SAAS=1' >> ../env.runit
gdk restart rails-web rails-background-jobs
GITLAB_SIMULATE_SAAS=1 bin/rails runner scripts/slack_duo_poc/seed.rb

Remove the line from env.runit and restart again to go back.

Real Slack install (optional)

You need a Slack app configured in Admin > Settings > GitLab for Slack app that points at your GDK. Events don't matter for setup, so you don't need a tunnel. Then sign in as slack-newbie, open /-/profile/slack/edit, pick Empty Co and approve in Slack.

Clean up

bin/rails runner scripts/slack_duo_poc/seed.rb cleanup          # removes fake installs and Duo claims (keeps users and groups)
bin/rails db:migrate:down VERSION=20261012163609                 # before switching back to master
git checkout master

Known gaps

  • No migration for existing workspaces, no moving Duo between groups, and no re-approval for older installs that lack the Duo permissions.
  • Guests pass the new membership check but are still blocked later: #632568 (closed).
  • Error replies in Slack are still private: #632567 (closed).
  • New code has few tests. The pipeline was skipped on purpose.

Merge request reports

Loading
Loading