Sign in with Slack (SIWS) links allow a user to share their Slack identity with your app when they click on a link from your service. When a user clicks on your link, Slack will utilize OpenID Connect (OIDC) standard to send over a user’s identity information.
Before continuing with this guide, you might want to read the following before proceeding:
Sign in with Slack links is a paid feature. Interested parties should fill out the interest form or reach out to partnersupport@slack-corp.com for more information.
Let's jump in!
In order to receive a user’s information when a link is clicked, you will first need to verify that you own your domain(s). This domain must be different from your production domain.
Please reach out to partnersupport@slack-corp.com to request Domain Verification be enabled for your team.
To verify a domain, locate your app from your Apps page then navigate to your app's "Domain Verification" page. The Domain Verification link is under the "Settings" section in the top of the left sidebar.
This should take you to: https://app.slack.com/app-settings/<team_id>/<app_id>/domain-verification
where you can add and verify domains for Sign in with Slack links.
Once you've added and verified your domains you will need to reach out to Slack to confirm your domains.
You will need to implement Sign in with Slack for your service using OpenID Connect.
Choose an existing OpenID Connect Relying Party client for your tech stack (or create your own by following the standard) and point it towards Slack’s provided OpenID configuration URL. For this guide, we are using Auth0 as our client, but feel free to use whichever you’d like.
Navigate to your App Configuration Oauth and Permissions
page and add a redirect URL where you would like the OpenID flow to redirect after it’s completed and click save.
For an Auth0 service, this may look like:
https://slacktest.us.auth0.com/login/callback
Keep track of your Client ID and Client Secret from the Basic Information Page.
For Logo URL, feel free to use this sample URL:
https://a.slack-edge.com/80588/marketing/img/meta/favicon-32.png
For Issuer URL, please use this URL (the key param will be required until we publicly release this feature):
https://slack.com/.well-known/openid-configuration
We support both Front Channel and Back Channel types.
https://slack.com/api/openid.connect.token
(This endpoint is subject to change - we will alert you if we change it)
openid profile email
but add the identity scopes from your Slack App scopes. It should look like this:openid profile email identity.basic identity.email identity.team identity.avatar
For reference, here is a fully filled out Auth0 Configuration page:
From the OpenID Connect page, click the Try button and this should now work!
We have noticed that using the Front Channel method means that cookies are not sent by default in Chrome once the form_post
actually posts due to the SameSite restriction. If this means nothing to you, feel free to ignore!
After the domain has been configured, verified and enabled, when a link (e.g. https://your-service.net/work-object/1) that conforms to the domain pattern is first clicked in Slack, Slack will prompt the user if they would like to additionally transfer their Slack identity to you. If users do not accept and decline 3 times, subsequent links clicked will not trigger this prompt.
If a user clicks Accept, Slack will redirect the user to an endpoint with a login hint to start the identity transfer.
If the user clicks Decline, we will simply redirect to the link clicked.
Slack will redirect to a login initiation endpoint that you have specified in your App Configuration Pages with the following parameters:
name | value | notes |
---|---|---|
iss | https://slack.com | |
login_hint | JWT-encoded target user information | Option to JWT decode this and check if the target user is already logged-in, bypassing the OpenID connect flow |
The OpenID Connect specification for Initiating Login from a Third Party specifies how this endpoint is used:
After receiving the request, your app will start an OpenID Connect authentication similar to the Sign in with Slack flow described above but appending the login_hint
parameter to the authorization URL.
When the flow is complete, there should be an additional key set with the claims called:
https://slack.com/target_uri
which is the URI that the user originally clicked. Note that Auth0 renames this key to:
https://slack:com/target_uri
What does SIWS links look like when it’s all setup in your app?
GET /siws/authorize?
response_type=id_token
&client_id=6371490080.1055357699042
&redirect_uri=https%3A%2F%2Fid.test.net%2Fsiws%2Fauth
&scope=openid%20email%20profile
&login_hint=T5J4Q04QG-W1H5Z2EHE-bjzess81jq7ehbvq6ewta90pllihsqor
&response_mode=form_post
&state=af0ifjsldkj
&nonce=n-0S6_WzA2Mj HTTP/1.1
Host: slack.com
login_hint
does not match an existing stored link click, the Authentication Request will fail.name | value |
---|---|
id_token | JWT-encoded payload |
expires_in | 300 |
state | matches state sent in Authentication Request |
After decoding, the JWT-encoded payload will include the following:
{
"iss": "https://slack.com",
"sub": "jsmith@slack-corp.com",
"aud": "6371490080.1055357699042",
"exp": 1592939535,
"iat": 1592939235,
"auth_time": 1592939235,
"nonce": "n-0S6_WzA2Mj",
"email": "bfan@slack-corp.com",
"locale": "en-US",
"name": "John Smith",
"given_name": "John",
"family_name": "Smith",
"picture": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/...",
"https://slack.com/user_id": "U06AXEE2U",
"https://slack.com/user_image_24": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/user_image_32": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/user_image_48": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/user_image_72": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/user_image_192": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/user_image_512": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/user_image_1024": "https://s3-us-west-2.amazonaws.com/...",
"https://slack.com/team_id": "T06AXEE2C",
"https://slack.com/team_name": "John Testy",
"https://slack.com/team_domain": "johntesty",
"https://slack.com/team_image_34": "https://slack.com/dev-cdn/v1587409668/...",
"https://slack.com/team_image_44": "https://slack.com/dev-cdn/v1587409668/...",
"https://slack.com/team_image_68": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-68.png",
"https://slack.com/team_image_default": true,
"https://slack.com/target_uri": "https://johnjiratest.test.net/browse/PLAT-1"
}
You MUST verify that the nonce
matches the one originally sent. It should also verify the JWT using the JWKS defined by Slack and verify that the JWT has not expired.
You can now check if an account with this email already exists. If it does not, you can automatically provision an account for this user. If it does, it will add Sign in with Slack as an additional login method for this account.