doc/development/ai_features/duo_in_slack.md
GitLab Duo in Slack responds when a user mentions the GitLab bot in a Slack channel or thread. Slack must be able to reach your GDK over the internet for this to work.
To test the feature locally, you must:
A GDK with GitLab Duo set up.
A CI/CD runner registered against your GDK,
tagged gitlab--duo. Use the docker executor: flows run in a Docker image, so the shell
executor does not work. For more information, see
Configure runners to execute flows.
A Slack workspace where you are an administrator. Use a Slack developer sandbox, not the GitLab workspace.
The slack_duo_agent feature flag enabled globally:
Feature.enable(:slack_duo_agent)
A default GitLab Duo namespace set on your user, with the Developer Flow turned on for that top-level group.
Some Slack features are only available on paid Slack plans, and a free workspace silently lacks them. A developer sandbox is a workspace with all paid features enabled, so use one as your test workspace.
To get a sandbox:
Sandboxes archive automatically after about six months, and the free plan includes a monthly provisioning limit, so reuse one sandbox rather than creating a new one per test.
Slack must reach your GDK, so you need a reverse tunnel that gives your GDK a public HTTPS URL.
[!warning] A tunnel exposes your local machine to the public internet. GitLab team members should get an approved exception, because the laptop firewall requirements prohibit circumventing the local firewall. Stop the tunnel when you finish. See this past security exception request as an example.
The following steps use ngrok, but any tunnel that terminates TLS and
forwards to your GDK works.
Install ngrok, then add the authentication token from your
ngrok dashboard:
ngrok config add-authtoken <your_token>
Claim your static domain on the Domains page of the ngrok dashboard. The free plan includes
one. A static domain means the tunnel URL survives restarts, so you configure the Slack app and
RAILS_HOSTS only once.
Start a tunnel to the host and port your GDK listens on, and pass your static domain:
ngrok http gdk.test:8080 --url=<your_static_domain>.ngrok-free.app
Start GDK with the RAILS_HOSTS set to your ngrok domain:
RAILS_HOSTS=<your_static_domain>.ngrok-free.app gdk start
Confirm that the tunnel reaches your GDK by opening the tunnel URL in a browser. You should see your GDK sign-in page (It's fine if assets don't load).
In your GDK, in the upper-right corner, select Admin.
Select Settings > General, then expand GitLab for Slack app.
Select Create Slack app. GitLab redirects you to Slack with the generated manifest.
If this returns a 502 Bad Gateway page from NGINX, see
NGINX returns 502 Bad Gateway when you create the Slack app.
Select your workspace, then Next, then select Create and Install.
On the Review app permissions page, select Allow, then select Go to App Settings.
Back in GitLab, in the GitLab for Slack app section:
In Slack, go to Your Apps, select your app, then select App Manifest.
Replace every occurrence of your GDK host (http://gdk.test:8080) with your tunnel URL,
except oauth_config.redirect_urls, which must stay as your GDK URL. Note the scheme change from http to https.
[!note] Editing these values in the Create Slack app page does not work, as Slack ignores the changes. This may be a bug that gets fixed at some point.
Select Save Changes.
Go to Install App and reinstall the app, so the new manifest gets applied.
Installing the app from Slack does not give GitLab a bot token. Install the app once more from
GitLab, which runs the OAuth exchange that stores the token on the SlackIntegration record:
Repeat these steps whenever you reinstall the app in Slack, because reinstalling mints a new bot token that GitLab does not receive.
@GitLab hi. If the bot is not in the channel,
Slack replies with a prompt to add it. Select Add them. Slack does not deliver the mention that
triggered the prompt, so mention the bot again.Run the first mention as a user who can create projects in the default GitLab Duo namespace. Slack
mentions carry no project context, so Ai::Messaging::DefaultProjectFlowResolver derives one from
your default GitLab Duo namespace and calls Ai::Messaging::WorkspaceProjectService, which finds the
duo-workspace project in that namespace or creates it.
If you later change the manifest to add scopes, select Install App > Reinstall to Workspace. Slack grants scopes at install time only, so new scopes take effect only after you reinstall.
502 Bad Gateway when you create the Slack appCreate Slack app redirects to Slack with the whole app manifest URL-encoded into the Location
header. The header is larger than the default proxy buffer in the GDK NGINX configuration, so NGINX
rejects the response and logs upstream sent too big header while reading response header from upstream in log/nginx/current.
To resolve this error, in nginx/conf/nginx.conf in your GDK directory, add the following to the
server block, next to the other proxy_ settings:
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
Then run gdk restart nginx. This file is generated from components/nginx/nginx.conf.erb, so
gdk reconfigure overwrites the change. To keep it, make the same change in the template.
account_inactiveintegrations_json.log records a Slack API error with "error": "account_inactive", and the bot
never reacts or replies. Slack received the mention and GitLab processed it, but GitLab holds a
revoked bot token, so every call back to Slack fails.
To resolve this error, give GitLab the current token again:
@mention failuresWhen the bot posts an error back to the thread, match the message against
GitLab Duo @mention failures,
which lists each message, its cause, and the fix. That page also describes the log fields to filter
on in log/integrations_json.log and log/sidekiq.log.
Two cases behave differently in local development:
nginx/logs/access.log in your GDK directory as a
POST /api/v4/integrations/slack/events from Slackbot, and in log/integrations_json.log with
Slack's IP address in meta.remote_ip. If neither log records the mention, Slack could not reach
your GDK: check that your tunnel is running and that RAILS_HOSTS includes the tunnel host, then
reverify the request URL in Slack. If the logs do record it, the mention arrived and the failure is
in the response, such as account_inactive.Could not set up the service account for the Duo Developer flow. The Developer Flow
might be turned off for your top-level group. In the group, go to Settings > GitLab Duo,
select Change configuration, and under Flow execution, turn on the Developer Flow.Ai::Messaging::WorkspaceProjectService creates the project with initialize_with_readme: true, so
the repository has a README.md commit on the default branch.
If the repository is not correctly initialized, flows have no default branch to check out and fail. If this happens, initialize the repository with a commit.