Progressive permissions for Slack apps
Leo Sjöberg • March 19, 2023
With Slack's deprecation of its legacy Workspace Apps, the ability to interactively request
further permissions was lost. However, you can still request an extend permission scope
using your own implementation. For my Slack App, Decisionlog,
I needed to request the channels:history
scope, which allows me to read the messages
in a channel or thread. However, I only need this scope when the user is trying to record
a decision from a message or for a thread (so that I can include the message in the decision,
and in the future help summarise the thread for them).
The key to this is to use the scope
parameter that is specified in the Slack OAuth URL.
In order to request additional scopes, simply add what you need to the scope
parameter.
One important caveat here is that it means you should not specify your optional scopes in
the Slack API configuration panel, as that changes the default scopes that are requested by
the "Add to Slack" button. As far as I can tell, however, the scope configuration in the
configuration panel are only used to generate the "Add to Slack" button, not impacting your
application's ability to request additional scopes.
Putting it into practice, my "Embeddable Slack button" looks like this:
1<a href="https://slack.com/oauth/v2/authorize?client_id=7886001392.4938525181617&scope=commands,chat:write,chat:write.public&user_scope="><img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcSet="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/[email protected] 2x" /></a>
As such, when I want to request the channels:history
scope, I simply add it to the scope
parameter:
-scope=commands,chat:write,chat:write.public // +scope=commands,chat:write,chat:write.public,channels:history //
Then, I implement a custom button in my Slack App's homepage to let the user grant the additional scope to the App.
When building applications, it's important to only request the permissions you need. This is especially true for ones like Slack Apps, where permission may be granted to your service to read all messages, which could very well contain sensitive information. In the case of Decisionlog, I only need to read the messages in a channel or thread when the user wants to include the message in the decision, meaning I can build both trust and a more secure application by not requesting extraneous permissions ahead of time.