Request the smallest set of bot scopes that makes your feature work, and nothing for later. Ask for user scopes only when the app must act on behalf of a person. Scopes accumulate across installations, so review them after every change, not only at launch.
What scopes decide
Slack's OAuth documentation puts it simply: during the OAuth flow you specify which scopes your app needs, and those scopes determine exactly which doors the access token can open. If your token leaks, the scopes are the blast radius.
The same page describes two token paths. A scope parameter in the authorize link requests scopes for the app's bot user. If you have a specific need to act on behalf of a user, you provide a user_scope parameter with requested user scopes instead of, or in addition to, the scope parameter. A bot token acts as the app. A user token acts as a person.
Scopes are additive
The documentation also notes that each installation can add scopes. Its example: if one install requests channels:history and a later install requests channels:read, both scopes end up associated. That means a long lived app can quietly collect permissions as features are added and old ones are dropped. Nobody removes the old ones unless they look.
A practical process
- List features, then API methods. For each feature, write down the Slack methods or events it uses.
- Map methods to scopes. The method reference lists the scopes each one needs.
- Request only that set. Leave out read access to history if the bot only posts messages.
- Prefer bot tokens. Use user tokens only when the action must be attributed to a person.
- Subscribe only to events you need. Event subscriptions are tied to the OAuth scopes granted at install.
- Review on every release. Compare the granted scopes to the current feature list and remove extras.
A quick comparison
| Need | Typical choice | Risk if over-scoped |
|---|---|---|
| Post an alert to one channel | Narrow bot scope for posting | A leaked token could post anywhere it is allowed |
| Read messages in channels it has joined | Read scope for those channels | Wider reading means more data exposed |
| Act as a user, such as setting status | User scope | Token carries a person's identity |
Treat a read scope as a data access decision, not a technical detail. Chat history often holds credentials, customer data and internal plans.
Ask your admins to review too
Workspaces can control which apps are approved, and security teams can review requested scopes before approving. Make that review easy: publish a short page that lists each scope and the feature behind it. See Slack app approval and restricting installs and OAuth scopes are not user permissions.
Protect the token itself
Tokens belong in a secrets store. Verify incoming requests with the signing secret, as in verifying a Slack request signature. Rate limits also apply to every method, so plan for 429 responses.
Where Safeguard fits
Safeguard's agent identity and policy features can help you scope what automated actors may do, and asset discovery helps you see which integrations exist. A free scan covers dependencies.
Quick check
If I remove a feature, are its scopes removed automatically?
Not necessarily. Scopes from earlier installs can remain associated, so review the granted list yourself.
Bot token or user token?
Use a bot token by default. Use a user token only when the action must run as a specific person.
Sources
- Installing with OAuth, Slack developer documentation
- Events API, Slack developer documentation
Last reviewed: 19 October 2026.