This feature has not been released publicly, and we politely request that you treat everything in this document as confidential.

All details outlined in this document are in beta. We may change the timeline, APIs, and functionality based on feedback from pilot testers like yourself, so you should be prepared to update your code accordingly.

Identity links

Identity links allows users to share their Slack information with you when they click a link from your service. When a user clicks your your link, we utilize OpenID Connect (OIDC) standard to send you their information.

Prerequisites

  1. Your Slack app is using granular permissions
  2. You are able to implement SIWS using OpenID Connect
  3. You are able to implement automatic provisioning and account linking within your product

In addition, you may want to catch up on this documentation first before continuing on:

  1. Sign In With Slack (SIWS)
  2. OpenID Connect 1.0 specification

Domain verification

In order to receive a user’s information when a link is clicked, you'll first need to verify that you own your domain(s).

Please reach out to partner engineering with a list of domains you'd like to verify for your test apps.

Implementing SIWS

The next step is to implement SIWS for your service using OpenID Connect. This is not publicly available, so you’ll need to complete the following steps.

1. Setting up Open ID

Choose an existing OpenID Connect Relying Party client for your tech stack (or create your own by following the standard) and point it toward Slack’s OpenID configuration URL. In this example we are using Auth0 as our client, but feel free to use whatever you’d like.

URLs

Navigate to your app's Oauth and Permissions and add a redirect URL where you want the OpenID flow to redirect after it’s completed. Click Save. For an Auth0 service, it may look like the following: https://slacktest.us.auth0.com/login/callback

You'll need to add user token scopes to enable SIWS. Add the following:

  • identity.basic
  • identity.email
  • identity.team
  • identity.avatar

Note your Client ID and Client Secret from the Basic Information page.

Navigate to your OpenID connect Relying Party client (Auth0), Enterprise, then Connections. Select OpenID Connect to create a new connection.

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, use this URL (the key parameter will be required until this feature is publicly released): https://slack.com/.well-known/openid-configuration?key=zQqzXfb677bpMKw0idKC5WkVLyqk04PWMsWYJDKqMUUuu

Front and Back Channels

We support both Front Channel and Back Channel types.

If you use Back Channel, you’ll need to enter your Client Secret as well. You’ll also need to click Issuer Details and check whether or not the Token Endpoint is filled in. If it is not filled in, please enter https://slack.com/api/openid.connect.token.

We 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!

(This endpoint is subject to change - we will alert you if we change it)

Scopes

Under Scopes, leave openid profile email, but add the identity scopes from your Slack App Scopes. It should look like the following when you’re done:

openid profile email identity.basic identity.email identity.team identity.avatar

Save your changes.

Finish up

For reference, here is a fully completed Auth0 configuration page:

From the OpenID Connect page, select Try and this should now work!

2. Implementing automatic account provisioning or linking

After the domain has been configured, verified, and enabled, Slack will prompt the user if they would like to additionally transfer their Slack identity to you after a link (e.g. https://your-service.net/work-object/1) that conforms to the domain pattern is clicked in Slack. 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'll redirect to the link clicked.

Slack will redirect to a login initiation endpoint that you have specified in your app's configuration with the following parameters:

name value notes
iss https://slack.com
login_hint JWT-encoded target user information Atlassian may 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 SIWS 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.

3. Final steps

What does everything look like once setup is completed? We're glad you asked!

  1. Your app will send an authentication request to a Slack endpoint (e.g. https://slack.com/openid/connect/authorize) as in the following example:
      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
  1. Slack will then verify the request but will not conduct end-user consent authorization; verification will proceed without prompting the user. If the login_hint does not match an existing stored link click, the authentication request will fail.
  2. Slack will send an authentication response to your app by sending a POST to your response endpoint (e.g. https://id.test.net/siws/auth) with the following parameters:
name value
id_token JWT-encoded payload
expires_in 300
state af0ifjsldkj (matches state sent in authentication request)
  1. After decoding, the JWT-encoded payload will include the following:

    {
        "iss": "https://slack.com",
        "sub": "imontoya@slack-corp.com",
        "aud": "6371490080.1055357699042",
        "exp": 1592939535,
        "iat": 1592939235,
        "auth_time": 1592939235,
        "nonce": "n-0S6_WzA2Mj",
        "email": "imontoya@slack-corp.com",
        "locale": "en-US",
        "name": "Inigo Montoya",
        "given_name": "Inigo",
        "family_name": "Montoya",
        "picture": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_512.png",
        "https://slack.com/user_id": "U06AXEE2U",
        "https://slack.com/user_image_24": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_24.png",
        "https://slack.com/user_image_32": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_32.png",
        "https://slack.com/user_image_48": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_48.png",
        "https://slack.com/user_image_72": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_72.png",
        "https://slack.com/user_image_192": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_192.png",
        "https://slack.com/user_image_512": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_512.png",
        "https://slack.com/user_image_1024": "https://s3-us-west-2.amazonaws.com/slack-files-dev2/avatars/2017-11-15/19281328432_18916452ce6b631c669f_1024.png",
        "https://slack.com/team_id": "T06AXEE2C",
        "https://slack.com/team_name": "Inigo Test",
        "https://slack.com/team_domain": "inigotest",
        "https://slack.com/team_image_34": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-34.png",
        "https://slack.com/team_image_44": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-44.png",
        "https://slack.com/team_image_68": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-68.png",
        "https://slack.com/team_image_88": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-88.png",
        "https://slack.com/team_image_102": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-102.png",
        "https://slack.com/team_image_132": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-132.png",
        "https://slack.com/team_image_230": "https://slack.com/dev-cdn/v1587409668/img/avatars-teams/ava_0003-230.png",
        "https://slack.com/team_image_default": true,
        "https://slack.com/target_uri": "https://inigojiratest.test.net/browse/PLAT-1"
    }
    
  2. 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.

  3. You can check whether 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 SIWS as an additional login method for this account.