Distributing Internal Slack Apps With Manifests: Version-Control Your Bot's Config
Click-ops Slack app config doesn't survive audits or new workspaces. Here's how app manifests let you version, review, and deploy your ops bots like real software.
- #slack
- #app-manifest
- #distribution
- #iac
- #devops
- #chatops
You built a great ops bot. Its scopes, slash commands, event subscriptions, and shortcuts all live in the Slack app-config UI — a web form you clicked through once and will never fully remember. Now you need to deploy it to a second workspace, recreate it after someone deletes it, or prove to an auditor exactly what permissions it holds. Suddenly that click-ops config is a liability: undocumented, un-reviewable, and impossible to reproduce.
App manifests fix this. A manifest is a YAML or JSON document that fully describes a Slack app’s configuration — name, scopes, commands, events, interactivity, everything. Put it in version control and your bot’s config becomes code: reviewable in PRs, diffable across changes, and reproducible across workspaces. For any bot you intend to operate seriously, this is the difference between an artisanal pet and a reproducible piece of infrastructure.
What a manifest contains
The manifest captures the entire app definition. A trimmed example for an ops bot:
display_information:
name: OpsBot
description: Internal DevOps automation
features:
bot_user:
display_name: opsbot
slash_commands:
- command: /deploy
description: Trigger a deploy
usage_hint: "[service] [version]"
- command: /k8s
description: Read-only cluster status
oauth_config:
scopes:
bot:
- chat:write
- commands
- channels:read
settings:
event_subscriptions:
bot_events:
- app_mention
interactivity:
is_enabled: true
socket_mode_enabled: true
Read that top to bottom and you know exactly what the bot can do and see. That’s the whole pitch: the manifest is a single reviewable source of truth for the bot’s capabilities, and the scopes block in particular is the security review — you can spot an over-permissioned bot in a diff instead of an audit.
Manifests as code review
Routing app changes through manifests means every capability change goes through a pull request. Want to add channels:history scope? That’s a diff a reviewer sees and questions: “why does the deploy bot need to read all channel history?” Compare that to someone quietly toggling a scope in the UI where nobody notices until the security review. Scope creep is the most common way bots become risky, and manifest-in-git is the cheapest control against it.
Store the manifest alongside the bot’s source so the config and the code that depends on it move together. A PR that adds a /rollback command updates both the manifest (the command definition) and the handler (the implementation) in one reviewable change.
Creating and updating apps from the manifest
Slack’s App Management API lets you create and update apps programmatically from a manifest, which is what turns this from documentation into deployment:
curl -X POST "https://slack.com/api/apps.manifest.create" \
-H "Authorization: Bearer $SLACK_CONFIG_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"manifest\": $(cat manifest.json)}"
There’s a matching apps.manifest.update for applying changes and apps.manifest.validate to lint a manifest in CI before you ever apply it. The configuration tokens that authorize these calls are themselves sensitive — treat them like any deploy credential, store them in your secrets manager, and rotate them.
A clean pipeline looks like: PR merges to main → CI validates the manifest → CI applies it via apps.manifest.update → the bot’s config now matches the repo. Your Slack app config is GitOps-managed, same as any other infrastructure.
Distribution: one app, many workspaces
If you’re rolling the same ops bot out across multiple workspaces — a common need in larger orgs or for a tool you share with other teams — the manifest is your template. Create the app from the same manifest in each workspace and the configuration is identical by construction, not by someone carefully re-clicking the same form four times. Differences become bugs you can spot, because they show up as a workspace whose config drifted from the manifest in the repo.
If you intend to list the app in the Slack App Directory for truly external distribution, note that this is the case where you’ll want the HTTP request model rather than Socket Mode — distributed apps need public endpoints. For internal multi-workspace use, Socket Mode plus a shared manifest is the lighter path.
Validate in CI so broken config never ships
Treat the manifest like any other code artifact and lint it before applying:
- Schema-validate with
apps.manifest.validateon every PR so a malformed manifest fails the build, not production. - Scope-diff check — flag any PR that adds a scope so a human explicitly approves new permissions. A few lines of CI comparing the scope list against the previous version makes scope creep impossible to merge silently.
- Dry-run on a staging workspace before applying to production workspaces.
This is the same discipline you’d apply to Terraform or a Helm chart, and Slack app config deserves it — a bot with chat:write in fifty channels and an event subscription to everything is real attack surface.
Make your bot reproducible this sprint
If your ops bots are configured by click-ops, export each one’s manifest, commit it next to the source, and switch to manifest-driven updates. You’ll gain reviewable permission changes, reproducible deployments, and an audit story that’s just git log. The next time someone asks “what can this bot do?” the answer is a file, not a memory.
For the surrounding patterns — building the bot, handling rate limits, and wiring AI in — see our other AI for Slack guides, and keep your shared automation prompts in a versioned prompt library so the whole config-as-code story extends to the AI parts too.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.