Skip to main content

Documentation Index

Fetch the complete documentation index at: https://allhandsai-docs-enterprise-slack-integration.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks an operator through enabling the @OpenHands Slack integration on a self-hosted OpenHands Enterprise (OHE) installation — both the Replicated VM-based install (see the Quick Start) and standalone Helm (Kubernetes Installation). Once enabled, end users can mention @openhands in any Slack channel or thread to start and follow up on conversations from Slack, exactly like they can on OpenHands Cloud.
If you are looking for the OpenHands Cloud Slack integration (no self-hosting involved), see Slack Integration instead — that page uses the All-Hands-managed Slack App and skips the steps below.

Overview

Unlike OpenHands Cloud, a self-hosted install needs its own Slack App so that Slack webhooks land on your domain rather than app.all-hands.dev. The configuration involves four phases:
  1. Create a Slack App for your install (one-time, by a Slack workspace admin).
  2. Configure OHE with the Slack App’s credentials (one-time, by the OHE operator).
  3. Install the Slack App into your workspace (one-time, by a Slack workspace admin).
  4. Link each user’s account in OpenHands ↔ Slack (per-user, self-service).
1

Verify prerequisites

2

Create the Slack App

3

Configure OpenHands Enterprise

4

Install the Slack App into your workspace

5

Have users link their Slack accounts

Prerequisites

Before you start, confirm:
  • OHE is already installed and reachable. You can sign in to OpenHands Enterprise at https://app.<your-base-domain> (e.g. https://app.mycompany.com).
  • Inbound HTTPS from the public internet terminates at your OHE ingress on https://app.<your-base-domain>/slack/*. Slack delivers webhooks from public IPs, so fully air-gapped installs are not supported by this integration today (Slack Socket Mode is disabled).
  • Valid TLS certificate on app.<your-base-domain>. Slack will reject webhook URLs with untrusted certificates.
  • A Slack workspace admin/owner is available to install the app and generate a short-lived Slack App Configuration Token.
  • A workstation with uv installed and outbound network access to slack.com (only needed for the optional helper script in Step 2).
Replace <your-base-domain> throughout this guide with the same domain you used during installation (the value behind KOTS_HOSTNAME or the ingress.host Helm value).

Step 1: Create the Slack App

You can mint the Slack App either with the helper script in OpenHands-Cloud (recommended) or by pasting the manifest into Slack’s UI. Either path produces the same app.
  1. Generate a Slack App Configuration Token:
    1. Sign in to https://api.slack.com/apps as a workspace admin/owner.
    2. In Your App Configuration Tokens, click Generate Token.
    3. Select your workspace and click Generate.
    4. Copy the access token (starts with xoxe.xoxp-). Treat it like a password — it is short-lived but is sufficient to create apps in your workspace.
  2. Clone OpenHands-Cloud and run the script:
    git clone https://github.com/OpenHands/OpenHands-Cloud.git
    cd OpenHands-Cloud
    
    export SLACK_CONFIG_TOKEN=xoxe.xoxp-...
    ./scripts/create_slack_app/create_slack_app.py \
      --base-domain <your-base-domain>
    
    Pass --dry-run to print what would be created without calling Slack. Pass --app-name "OpenHands (Staging)" to differentiate multiple installs in the same workspace.
  3. The script prints three values. Save them now — Slack will let you retrieve them again from the app’s “Basic Information” page, but the script does not store them anywhere:
    Slack Client ID:        ...
    Slack Client Secret:    ...
    Slack Signing Secret:   ...
    
The script registers the following URLs on the new Slack App (all rooted at https://app.<your-base-domain>):
Slack settingURL
OAuth Redirect URL/slack/install-callback
Event Subscriptions Request URL/slack/on-event
Interactivity Request URL/slack/on-form-interaction
Options Load URL/slack/on-options-load
…and requests these bot scopes (no user scopes): app_mentions:read, chat:write, users:read, channels:history, groups:history, mpim:history, im:history. Socket Mode, Org Deploy, and Token Rotation are intentionally disabled to match what the OHE backend expects today.

Option B: Paste the manifest into Slack’s UI

If you can’t run the script (e.g. your workstation has no outbound Slack access), open https://api.slack.com/appsCreate New AppFrom an app manifest, choose your workspace, and paste the YAML below. Replace <your-base-domain> first.
display_information:
  name: OpenHands
features:
  bot_user:
    display_name: OpenHands
    always_online: false
oauth_config:
  redirect_urls:
    - https://app.<your-base-domain>/slack/install-callback
  scopes:
    bot:
      - app_mentions:read
      - chat:write
      - users:read
      - channels:history
      - groups:history
      - mpim:history
      - im:history
settings:
  event_subscriptions:
    request_url: https://app.<your-base-domain>/slack/on-event
    bot_events:
      - app_mention
  interactivity:
    is_enabled: true
    request_url: https://app.<your-base-domain>/slack/on-form-interaction
    message_menu_options_url: https://app.<your-base-domain>/slack/on-options-load
  org_deploy_enabled: false
  socket_mode_enabled: false
  token_rotation_enabled: false
After creating the app, copy Client ID, Client Secret, and Signing Secret from the app’s Basic Information page.
When Slack verifies your Event Subscriptions Request URL, your OHE install must already be reachable at https://app.<your-base-domain>/slack/on-event. If you create the Slack App before OHE is running, Slack will mark the URL as unverified and you’ll need to click “Retry” after finishing Step 3.

Step 2: Configure OpenHands Enterprise

Pick the path that matches how OHE is deployed.
  1. Open the Replicated admin console at https://<admin-console-host>:30000 and sign in.
  2. Navigate to Config → Enable Slack (or search “Slack” in the config side panel).
  3. Set the following values:
    FieldValue
    Enable Slack Integration✅ on
    Slack Client IDfrom Step 1
    Slack Client Secretfrom Step 1
    Slack Signing Secretfrom Step 1
  4. Click Save config and then Deploy the new version.
  5. Wait for the deployment to reach Ready — Replicated will roll the integrations pod with the new secrets and environment variables.
Behind the scenes this:
  • Creates a Kubernetes Secret/slack-auth holding the client and signing secrets.
  • Sets slack.enabled=true, slack.clientId=<client-id>, and ENABLE_V1_SLACK_RESOLVER=true on the integrations service.
  • Exposes /slack/* on the integrations ingress on port 3000.
Confirm the integrations pod restarted with the new environment:
kubectl -n openhands set env deployment/openhands-integrations --list \
  | grep '^SLACK_'
You should see SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_SIGNING_SECRET, and SLACK_WEBHOOKS_ENABLED=true.

Step 3: Install the Slack App into your workspace

With OHE configured, point your browser at:
https://app.<your-base-domain>/slack/install
This redirects through Slack’s OAuth v2 flow and then through OpenHands’ Keycloak login. A workspace admin/owner should complete this step first — they will be granting the OpenHands bot permission to read mentions and post messages in your workspace. After approval you’ll see OpenHands Authentication Successful! Slack will also mark the Event Subscriptions Request URL as verified.
If Slack reports missing_scope after install, the most likely cause is that the manifest was edited to drop one of the *:history scopes. Re-run Step 1 (or fix the scopes in the Slack App OAuth & Permissions page) and then re-install via the same URL.
@OpenHands will only respond to users whose Slack identity has been linked to an OpenHands user. Every user — including the admin who installed the app — needs to do this once. They have two options:
  • From OpenHands: sign in at https://app.<your-base-domain>, open Settings → Integrations, and click Install OpenHands Slack App.
  • From Slack: the first time they mention @openhands, the bot will reply with a one-time login link that completes the same flow.
Either path produces the same record in the slack_users table, mapping the Slack user ID to a Keycloak (OpenHands) user. Once linked, any conversation started from Slack runs as that OpenHands user — using their LLM keys, provider tokens, and organization.

Using the integration

Day-to-day usage is identical to OpenHands Cloud — see Working With the Slack App for screenshots and the “mention @openhands in a thread” follow-up flow. A few self-hosted specifics worth knowing:
  • Repo selection. When a user starts a new conversation without an obvious repo in the message, OpenHands posts an ephemeral repo picker. The picker calls back to /slack/on-options-load on your domain and lists repositories the user can access through their linked Git provider.
  • Thread ownership. Only the user who started a thread conversation can @openhands in follow-up replies — other workspace members mentioning the bot in the same thread will get an “not authorized to send messages to this conversation” response. This is intentional until per-org access lands.
  • Conversation links. The bot’s “I’m on it!” reply links to https://app.<your-base-domain>/conversations/<id>. Users must be signed in to OHE to view it.

Limitations

  • No Slack Socket Mode. Your OHE install must be reachable from the public internet on https://app.<your-base-domain>/slack/*. Air-gapped installs cannot use this integration today.
  • No token rotation. The bot uses a long-lived xoxb- token issued at install time. If you regenerate the Slack App’s credentials, re-run Steps 2 and 3.
  • Single Slack App per install. The OHE backend assumes one Slack App per deployment. To support multiple workspaces, install the same Slack App into each workspace via Step 3 — do not create separate apps.
  • Slack Connect / externally shared channels are not supported for posting from the bot.

Troubleshooting

Slack could not reach https://app.<your-base-domain>/slack/on-event from the public internet, or the TLS certificate isn’t trusted. Verify from a machine outside your network:
curl -i https://app.<your-base-domain>/slack/on-event
You should get an HTTP response (a 403 is expected and fine — it means the route exists). If the request times out or the certificate is rejected, fix DNS / firewall / TLS before clicking Retry in Slack’s Event Subscriptions panel.
  1. Check that SLACK_WEBHOOKS_ENABLED=true is set on the integrations pod. If it is missing, your OHE deployment did not re-roll after Step 2 — redeploy.
  2. Tail the integrations pod logs and mention @openhands again. You should see a slack_on_event log line. If you don’t, Slack isn’t reaching your install.
  3. If you see slack_on_event followed by slack_is_duplicate, Slack is retrying an old delivery — wait 60 seconds and try a fresh message.
The Slack App is missing one of the bot scopes listed in Step 1. Open the app’s OAuth & Permissions page in Slack, add the missing scope, then re-install via https://app.<your-base-domain>/slack/install. Users do not need to re-link.
  1. Regenerate the Slack App’s Client Secret / Signing Secret on Slack’s app config page.
  2. Update them in Step 2 (Replicated admin console or the Helm secret).
  3. Redeploy OHE so the integrations pod picks up the new values.
  4. Existing user account links remain valid — no need to re-run Step 4.

Reference