Slack Marketplace
This guide defines the first public Slack listing for Threada.
Positioning
Threada for Slack turns Slack requests into governed Threada WorkItems. Your team can capture requests where work starts, then review drafts, evidence, approvals, and audit history in Threada.
The first listing must stay narrow:
- Create WorkItems from Slack.
- Route the WorkItem to a configured pack and queue.
- Return an immediate acknowledgement to Slack.
- Keep evidence, approvals, action proposals, and execution history in Threada.
Do not describe Slack direct messages, channel administration, workspace export, file reads, historical message search, or bulk actions as live until they are executable end to end and reflected in the integration index.
The runtime now supports a governed Slack chat.postMessage channel action for
tenant integrations that have a tenant-scoped Slack bot-token secret with
recorded chat:write scope evidence. Authenticated tenant admins can create
that runtime binding through the directory credential route. Keep the first
public Marketplace listing command-only unless the submitted Slack app also
requests chat:write, persists/revokes the OAuth bot token through Secret
Manager, and has reviewer smoke evidence for the post-message workflow.
Current status
Slack is live as a tenant-scoped runtime intake channel. The public slash
command endpoint is implemented at
POST /api/v1/integrations/slack/commands; it verifies Slack request
signatures, resolves slack_team_id against runtime integration metadata, and
creates a WorkItem from mapped Slack social channels.
The public Marketplace install surface is also implemented in the public BFF:
GET /api/v1/integrations/slack/oauth/startstarts OAuth from an authenticated Studio admin session with encrypted and authenticated state.GET /api/v1/integrations/slack/oauth/callbackexchanges the Slack code, records non-secret installation metadata, and redirects back to Studio.POST /api/v1/integrations/slack/eventsverifies Slack signatures, responds to URL verification, and disables the runtime installation onapp_uninstalled.POST /api/v1/integrations/slack/directory-installlets authenticated tenant admins store a Slack bot token in Secret Manager and upsert a runtime-bound Slack integration for governedslack_post_messageactions.
Studio connector readiness can start the Slack OAuth flow for the selected pack, show returned Slack workspace installs, and bind an unbound Slack runtime integration to that pack while preserving workspace, Enterprise Grid, app, and installation-status metadata.
Studio runtime channels can also bind a Slack channel ID to that installed
workspace by saving a social channel with Slack as the platform, the Slack
channel ID as the page identifier, and the pack-bound Slack integration as the
channel integration. The Slack command router uses that channel record to decide
whether /threada can create a WorkItem for the Slack channel.
Accepted /threada commands return Slack-visible acknowledgement text with a
direct Work shell link to the created WorkItem, using the mapped channel’s pack
key and the configured Work base URL.
Slack command outcomes that happen after signature verification return Slack-visible plain text for reviewable states: setup-required runtime responses, not-authorized failures, invalid command text, and retry-later runtime failures.
Governed Slack channel posting is implemented in runtime automation as an action
proposal/execution path. It calls Slack Web API chat.postMessage, requires a
tenant Slack integration secret containing bot_token, access_token, token,
or a raw token, and requires recorded slack_bot_token_granted_scopes metadata
that includes chat:write. The authenticated directory credential install route
creates that Secret Manager/runtime binding for tenant-admin setup. Command-only
OAuth installs record their install scopes separately as
slack_install_granted_bot_scopes and do not make the integration post-message
ready.
Public Marketplace packaging is not complete. The submission pack is drafted in Slack Marketplace submission pack, but the remaining submission gates are final active-workspace evidence proving at least five active workspaces, live approval evidence, filled reviewer context values that match the evidence bundle, and the owner-confirmed headquarters country required by Slack’s dashboard form. The release wrapper can emit a canonical Slack readiness artifact after dev and prod deploys, and the marketplace handoff/package-generation scripts turn that release evidence plus live review proof into a sanitized Slack submission package once the remaining external evidence gates clear.
Target app surfaces
Use a slash command for v1. It creates value without broad message-history permissions and is easier to explain during review.
Future app mentions or message shortcuts can be added after the same install and tenant-binding model is proven.
Set the slash command request URL to:
https://api.threada.ai/api/v1/integrations/slack/commands
Set the OAuth redirect URL to:
https://api.threada.ai/api/v1/integrations/slack/oauth/callback
Set the Events API request URL to:
https://api.threada.ai/api/v1/integrations/slack/events
The starter manifest at docs/integrations/slack-app-manifest.example.json is
a target template only. Do not submit it until the referenced OAuth callback,
slash command endpoint, Events API URL, install metadata mapping, and Studio
workspace/channel binding are validated in the deployment environment being
reviewed. Slack Marketplace review also needs the app’s public distribution
setting enabled, at least five active workspaces, an added app collaborator, and
a tested install/start URL that can take reviewers to Slack OAuth for that same
app.
Scope justification
| Scope | Reason |
|---|---|
commands | Receives /threada invocations so users can create governed WorkItems from Slack. |
chat:write | Optional governed channel posting through runtime automation. Do not request for the command-only v1 listing unless the submitted app stores/revokes the bot token through Secret Manager and reviewer smoke evidence covers chat.postMessage. |
app_mentions:read | Optional future event surface for mention-driven intake. Do not request until implemented. |
channels:read | Optional setup helper for channel selection. Keep optional unless Studio setup requires it. |
Scopes that should not be requested for the first listing:
channels:history,groups:history,im:history,mpim:history.files:read.search:read.admin.*.- user-token scopes.
Store listing draft
Use Slack Marketplace submission pack as the submission control sheet for the current listing copy, app settings, asset shot list, reviewer test notes, and external evidence checklist.
Short description:
Create governed Threada WorkItems from Slack requests.
Long description:
Threada helps teams turn operational requests into governed work. Use Threada from Slack to capture a request, route it to the right pack and queue, and continue review in Threada with drafts, evidence, approvals, and audit history. Threada is built for teams that need AI-assisted work without losing control over policy, review, or execution.
Primary category:
Productivity
Secondary fit:
Workflow and business management
Support copy:
Install Threada in Slack, map a channel to a Threada pack in Studio, then use
/threadato create a WorkItem from a request or escalation.
Public setup guide
Use Slack setup and support as the public setup and support
page for the v1 listing. It covers requirements, OAuth install, Studio
workspace/channel mapping, /threada usage, disconnect, uninstall, retained
data, and support/security contacts.
Data handling
The listing and setup guide must say that Threada receives the command payload needed to create a WorkItem, including Slack workspace, channel, user identifier, command text, and request metadata. Threada should not claim to read Slack channel history, files, private channels, or direct messages in v1.
The command-only v1 OAuth flow intentionally does not persist raw Slack OAuth
tokens; runtime installation metadata records
slack_oauth_token_persisted=false. The governed post-message action can run
only for tenant integrations that already have a tenant-scoped bot-token secret,
including those installed through
POST /api/v1/integrations/slack/directory-install.
If a public Marketplace version requests Web API scopes such as chat:write,
store, rotate, and revoke the OAuth bot token through Secret Manager before
requesting those scopes.
Non-secret install metadata may be stored in tenant-scoped runtime integration and channel records. Uninstalling disables the installation and preserves audit history for already-created WorkItems.
Runtime integration metadata must include slack_team_id; include
slack_api_app_id and slack_enterprise_id when known so command routing and
lifecycle handling can reject cross-app or Enterprise Grid mismatches.
Installation status and timestamps are stored as metadata so uninstall can be
audited.
The public BFF receives Slack credentials from Secret Manager values
slack-command-signing-secret-<env>, slack-oauth-client-id-<env>,
slack-oauth-client-secret-<env>, and slack-oauth-state-secret-<env>,
mounted as SLACK_COMMAND_SIGNING_SECRET, SLACK_OAUTH_CLIENT_ID,
SLACK_OAUTH_CLIENT_SECRET, and SLACK_OAUTH_STATE_SECRET.
slack-oauth-state-secret-<env> must be a non-placeholder random secret with
at least 32 bytes, for example output from openssl rand -base64 32; the BFF
uses it to encrypt and authenticate stateless OAuth callback state.
SLACK_OAUTH_REDIRECT_URL is deployment-derived as
https://api.threada.ai/api/v1/integrations/slack/oauth/callback in
production and https://api.<env>.threada.ai/api/v1/integrations/slack/oauth/callback
outside production. Do not put Slack signing secrets, OAuth client secrets, or
tokens in repo files, Pulumi config, logs, or review evidence.
Acceptance criteria
- OAuth install succeeds for a fresh Slack workspace.
- Slack public distribution is enabled for the submitted app.
- The Marketplace install/start URL reaches the public setup page and sends reviewers to Studio, where a signed-in tenant admin starts OAuth for the submitted app.
- Studio shows the Slack workspace install and binds it to the selected pack.
- Studio maps a Slack channel ID to the pack-bound Slack integration as an enabled Slack social runtime channel.
- Slash command succeeds from a mapped channel and returns a WorkItem link.
- Slash command from an unmapped channel returns an explicit setup-required response.
- Invalid Slack signatures fail closed.
- Uninstall disables future command handling for that workspace.
- Store screenshots, and the optional video if used, match the production behavior being submitted.
- If the listing claims governed Slack posting, the submitted Slack app requests
chat:write, the bot token is persisted and revoked through Secret Manager, and reviewer smoke evidence coverschat.postMessage. Otherwise keep post-message out of public listing copy. task marketplace:slack -- public-surface-checkpasses for the public setup, Marketplace, security, privacy, and terms pages.task marketplace:slack -- distribution-evidencewrites sanitized proof that public distribution is enabled for the submitted Slack app.task marketplace:slack -- active-workspaces-evidencewrites sanitized proof that the submitted Slack app has at least five active workspaces over Slack’s 28-day activity window.task marketplace:slack -- collaborators-evidencewrites sanitized proof that the submitted Slack app has at least one added collaborator, matching Slack Marketplace maintenance requirements.task marketplace:slack -- approvals-evidencewrites sanitized proof that legal, support, security, product, and engineering signoffs apply to the submitted Slack app.task marketplace:slack -- install-flow-checkpasses for the submitted install/start path and writes sanitized evidence for the public setup page or a validated Direct Install URL.task marketplace:slack -- dashboard-fieldswrites the Slack dashboard copy/paste artifact, andtask marketplace:slack -- evidence-statusreports no dashboard missing/blocked item for owner-provided values.task deploy:release -- --yes --slack-marketplace-readinesswrites the release-owned Slack readiness artifact after dev and prod deploys. Use the commit-scoped artifact as the source of truth for marketplace handoffs.task marketplace:slack -- action-planwrites sanitized JSON and Markdown handoff files from the current readiness status so owners can close any remainingmissingorblockeditems without copying terminal output. Run it with--check-install-pagebefore install-flow evidence capture so live public setup page deploy lag is visible in the handoff.- Add future Slack Marketplace automation as a registered
task marketplace:slack -- <subcommand>path rather than as a separate package script, so generated handoffs and release readiness stay on one CLI.
See the full launch runbook in integration-store-launch.md.